/**************************************************************/
/*  Description : Functions for interacting with the database */
/*      Version : 1.00                                        */
/*       Author : Rob Rademeyer                               */
/*    Copyright : © Copyright 2003 by Insight Solutions       */
/* Date Written : 26/07/2003                                  */
/*    File Path : w:\php\functions_validate.php               */
/*     Platform : PHP                                         */
/*     Contains : valid_fields($array)                        */
/*                valid_email($email)                         */
/*                valid_pair($left, $right)                   */
/*                valid_length($string, $min, $max)           */
/*                valid_password($pass1, $pass2, $min, $max)  */
/*                build_field_name($field)                    */
/**************************************************************/

var fnSendEmailSuccess = function(o) {
  // Populate the <div> with the response
  document.getElementById('emailmessage').innerHTML = o.responseText;
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
};

var fnSendEmailFailure = function(o) {
  // Populate the <div> with the response
  document.getElementById('emailmessage').innerHTML = 'Unable to send email for this user...!<br />' + o.responseText;
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
};

var callbackSendEmail = {
   success: fnSendEmailSuccess,
   failure: fnSendEmailFailure
};

/*------------------------------------------------------------*/
/* function used to send send an email to a supervisor which  */
/* contains a user's password...                              */
/*------------------------------------------------------------*/
function fnSendEmail() {
  // Turn on the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'block');
  // Get the values from the <INPUT> fields
  var id = document.getElementById('peopleID').value;
  var rc = document.getElementById('selectRecipient').value;
  // Build the URL
  var vURL = 'admindetails.php?id=' + id + '&type=1&recipient=' + rc;
  // Fire the AJAX request to get the additional details
  YAHOO.util.Connect.asyncRequest('GET', vURL, callbackSendEmail, null);
}

/*------------------------------------------------------------*/
/* function used on the Job capture form to load the selected */
/* date from the calendar into a hidden field...              */
/*------------------------------------------------------------*/
function fnUpdateJobStartDate(type, args, obj) {
  //oTarget = document.getElementsByName('req_title')[0];
  oTarget.value = args[0];
}


/*------------------------------------------------------------*/
/* */
/*------------------------------------------------------------*/
var displayInfoSuccess = function(o){
  // Populate the <div> with the response
  document.getElementById('info').innerHTML = o.responseText;
  // Create the new button
  var oButton = new YAHOO.widget.Button('sendEmail');
  // Attach the onClick event to the button
  oButton.addListener("click", fnSendEmail);
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
};

var displayInfoFailure = function(o){
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
  // Advise the user that it has not worked
  document.getElementById('info').innerHTML = 'Unable to fetch additional details for this user...!';
};

var callbackDisplayInfo = {
  success: displayInfoSuccess,
  failure: displayInfoFailure
};

/*------------------------------------------------------------*/
/* */
/*------------------------------------------------------------*/
var displayInfoAdvertSuccess = function(o){
  // Populate the <div> with the response
  document.getElementById('info').innerHTML = o.responseText;
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
};

var displayInfoAdvertFailure = function(o){
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
  // Advise the user that it has not worked
  document.getElementById('info').innerHTML = 'Unable to fetch additional details for this advert...!';
};

var callbackDisplayInfoAdvert = {
  success: displayInfoAdvertSuccess,
  failure: displayInfoAdvertFailure
};

/*------------------------------------------------------------*/
/* Formatter for links in a YUI table - displays the PDF icon */
/* with the actual link as an <a href="">...                  */
/*------------------------------------------------------------*/
var myFormatLinkImagePDF = function(elCell, oRecord, oColumn, oData) {
  //elCell.innerHTML = '<a href=' + oData + '><img src="images/pdficon.gif" border="0" alt="Click to open PDF" width="17" height="17" /></a>';
  // Break up the Owner Name and the Owner ID
  var vPieces  = oData.split("|");
  vSize = vPieces[0];
  vPath = vPieces[1];
  // Work out which icon to use
  if (vSize > 500000) {
    vIcon = 'images/pdficonb.gif';
    // Format the file size correctly
    vSizeStr = 'WARNING - large download [' + addCommas(vSize) + ' bytes]!';
  } else {
    vIcon = 'images/pdficons.gif';
    // Format the file size correctly
    vSizeStr = addCommas(vSize) + ' bytes';
  }
  elCell.innerHTML = '<a href=# onclick="window.open(\''+ vPath + '\', \'winPDF\', \'width=640,height=480\')"><img src="' + vIcon + '" border="0" alt="Click to open PDF" width="17" height="17" title="' + vSizeStr + '" /></a>';
};

/*------------------------------------------------------------*/
/* Formatter for links in a YUI table - displays the "i" icon */
/* via a Javascript function called by the 'onclick' event... */
/*------------------------------------------------------------*/
var myFormatLinkImageInfo = function(elCell, oRecord, oColumn, oData) {
  // Build a Unique ID for the element
  var vID = '' + Math.random();
  vID = vID.substring(2);
  vID = 'id' + vID;
  // Now populate the cell
  elCell.innerHTML = '<img src="images/iconview.png" id="' + vID + '", border="0" alt="Click to view Description" width="16" height="16" onclick="displayInfoSpecial(\''+ oData +'\', this.id);" />';
};

/*------------------------------------------------------------*/
/* Formatter for links in a YUI table - displays a standard   */
/* link as an <a href=""> which when clicked, opens a new     */
/* populated via a PHP script...                              */
/*------------------------------------------------------------*/
var myFormatLinkOwner = function(elCell, oRecord, oColumn, oData) {
  // Break up the Owner Name and the Owner ID
  var vPieces  = oData.split("|");
  //Now populate the cell
  elCell.innerHTML = '<a href=# onclick="window.open(\'viewowner.php?ownerid=' + vPieces[0] + '\', \'winOWNER\', \'width=480,height=480,scrollbars=yes\')">' + vPieces[1] + '</a>';
};

/*------------------------------------------------------------*/
/* Formatter for links in a YUI table - displays a standard   */
/* link as an <a href=""> which when clicked, opens a new     */
/* populated via a PHP script...                              */
/*------------------------------------------------------------*/
var myFormatLinkProduct = function(elCell, oRecord, oColumn, oData) {
  // Break up the Owner Name and the Owner ID
  var vPieces  = oData.split("|");
  //Now populate the cell
  elCell.innerHTML = '<a href=# onclick="window.open(\'viewproduct.php?productid=' + vPieces[0] + '&peopleid=' + vPieces[1] + '\', \'winOWNER\', \'width=480,height=520,scrollbars=yes\')">' + vPieces[2] + '</a>';
};

/*------------------------------------------------------------*/
/* Pass in an ELEMENT and it will create a local variable of  */
/* type YUI Panel, which is used by the "info" buttons...     */
/*------------------------------------------------------------*/
function fnDressPanel(vContext) {
 var oPanel = new YAHOO.widget.Panel(vContext);
 return oPanel;
}

/*------------------------------------------------------------*/
/* Ensures NOTHING is selected for a specific calendar [myCal]*/
/*------------------------------------------------------------*/
function clearCalendar(type, args, obj) {
  // Ensure that EVERYTHING is deleted
  myCal.deselectAll();
  myCal.render();
}

/*------------------------------------------------------------*/
/* Function whihc ensures that FIVE days are selected when a  */
/* user clicks on a specific date; knows how to handle the    */
/* weekends i.e. does not count them as part of the 5 days... */
/*------------------------------------------------------------*/
function updateCalendar(type, args, obj) {
  //var vDate = new Array();
  vDate    = args[0];
  vDateStr = vDate.toString();
  vDates   = vDateStr.split(",");

  // Build Javascript date objects
  var vDateL = myCal.toDate(vDates);
  var vDateR = myCal.toDate(vDates);

  // Get the end of the 5 day date range, catering for weekends
  switch(vDateL.getDay()){
    case 0:
      vDateR.setDate(vDateL.getDate()+5);
      break;
    case 1: // Monday
      vDateR.setDate(vDateL.getDate()+4);
      break;
    default:
      vDateR.setDate(vDateL.getDate()+6);
  }

  // Build the range for the calendar
  var vRangeL  = (vDateL.getMonth()+1) + "/" + vDateL.getDate() + "/" + vDateL.getFullYear();
  var vRangeR  = (vDateR.getMonth()+1) + "/" + vDateR.getDate() + "/" + vDateR.getFullYear();
  var vRange   = vRangeL + "-" + vRangeR;
  // Apply the range
  myCal.cfg.setProperty("selected", vRange);
  myCal.render();
  // Build the range for the hidden fileds
  vRangeL  = vDateL.getFullYear() + "/" + (vDateL.getMonth()+1) + "/" + vDateL.getDate();
  vRangeR  = vDateR.getFullYear() + "/" + (vDateR.getMonth()+1) + "/" + vDateR.getDate();
  // Update the hidden fields
  document.bookSpecial.req_datelower.value = vRangeL;
  document.bookSpecial.req_dateupper.value = vRangeR;
}

/*------------------------------------------------------------*/
/* Pass in a <div> & it will be skinned as a YUI calendar...  */
/*------------------------------------------------------------*/
function fnDressCalendar(vCalendarDiv)
{
  // create & render the calendar
  var oCal = new YAHOO.widget.Calendar("idCalendar", vCalendarDiv);
  oCal.render();

  // subscribe to selectEvent
  oCal.selectEvent.subscribe(updateCalendar, myCal, 0);
  oCal.deselectEvent.subscribe(clearCalendar, myCal, 0);

  // Send the calendar back so we can refer to it again
  return oCal;
}

/*------------------------------------------------------------*/
/* Create a calendar in the passed in <div> on the Job page.  */
/*   vCalendarDiv: ID of the <DIV> to render the calendar...  */
/*        vTarget: Name of the <INPUT> to hold the date...    */
/*------------------------------------------------------------*/
function fnDressCalendarJobs(vCalendarDiv, vTarget) {
  // Render the calendar from the HTML
  var oCal = new YAHOO.widget.Calendar(vCalendarDiv);
  oCal.render();
  // Find the <INPUT> which was passed in as vTarget
  oTarget = document.getElementsByName(vTarget)[0];

  // Subscribe to the custom event - note that the second arguement is ANY object
  // you want to pass in to which you want your callback function to have access
  // See fnUpdateJobStartDate for how it's used'
  oCal.selectEvent.subscribe(fnUpdateJobStartDate, oTarget);

  return oCal;
}

/*------------------------------------------------------------*/
/* Pass in a tab name & it will be skinned as a YUI tab...    */ 
/*------------------------------------------------------------*/
function fnDressTabs(vTabName)
{
  var myTabs = new YAHOO.widget.TabView(vTabName); 
}

/*------------------------------------------------------------*/
/* In the Registration form, builds the drop down list...     */
/*------------------------------------------------------------*/
function fnDressRegisterSelections(vAccountType) {
  // Declare some variables (without type information)
  var oSource;
  var oTarget;
  var oOptions;
  var oLabel;
  var vLabel;

  // Build an object from the JSON string
  oSource = document.getElementsByName('req_accounttype')[0];
  oTarget = document.getElementsByName('req_type')[0];
  oLabel  = document.getElementById('type');

  var vID     = oSource.options[oSource.selectedIndex].value;
  // Work out which lookup table we are going to use
  switch(vID) {
    case '1000001':
      oOptions = YAHOO.lang.JSON.parse(mediaType);
      vLabel   = 'Media Type:';
      break;
    case '1000002':
      oOptions = YAHOO.lang.JSON.parse(companyType);
      vLabel   = 'Company Type:';
      break;
    case '1000003':
      oOptions = YAHOO.lang.JSON.parse(companyType);
      vLabel   = 'Company Type:';
      break;
  }

  // Set the label correctly
  if (oLabel !== null) {oLabel.innerHTML = vLabel;}

  // Empty the current drop-down list
  oTarget.options.length = 0;
  // Iterate through the items and load the drow-down list
  for (var i=0; i<oOptions.Items.length; i++) {
    var vBits = oOptions.Items[i];
    vOption = new Option(vBits[0], vBits[1], vBits[2], vBits[3]);
    oTarget.options[oTarget.options.length] = vOption;
  }
}

/*------------------------------------------------------------*/
/* In the Ad Booking form, builds the drop down list...       */
/*------------------------------------------------------------*/
function fnDressRatecardSelections() {
  // Find the objects you need to work with
  var oSource = document.getElementsByName('req_products')[0];
  var oTarget = document.getElementsByName('req_ratecards')[0];

  // Get the currently selected ID
  var vID = "ID" + oSource.options[oSource.selectedIndex].value;

  // Declare the variables & populate them
  var oOptionz = YAHOO.lang.JSON.parse(vRatecard);
  var oOptions = oOptionz[vID];

  // Empty the current drop-down list
  oTarget.options.length = 0;

  // Iterate through the items and load the drop-down list
  vOption = new Option('No ClickThru to ratecard', '1000000', 'False', 'True');
  oTarget.options[oTarget.options.length] = vOption;
  for (var i=0; i<oOptions.length; i++) {
    var vBits = oOptions[i];
    vOption   = new Option(vBits[0], vBits[1], vBits[2], vBits[3]);
    oTarget.options[oTarget.options.length] = vOption;
  }
}

/*------------------------------------------------------------------------------
Generic function for filtering drop down lists - pass in
 vSource: string identifying the source <SELECT>
 vTarget: string identifying the source <SELECT>
   vData: object holding all of the data
------------------------------------------------------------------------------*/
function fnFilterDropdownList(vSource, vTarget, vData) {
  // Find the objects you need to work with
  var oSource = document.getElementsByName(vSource)[0];
  var oTarget = document.getElementsByName(vTarget)[0];

  // Get the currently selected ID
  var vID = "ID" + oSource.options[oSource.selectedIndex].value;

  // Declare the variables & populate them
  var oOptionz = YAHOO.lang.JSON.parse(vData);
  var oOptions = oOptionz[vID];
 
  // Empty the current drop-down list
  oTarget.options.length = 0;

  // Iterate through the items and load the drop-down list
  for (var i=0; i<oOptions.length; i++) {
    var vBits = oOptions[i];
    vOption   = new Option(vBits[1], vBits[0], vBits[2], vBits[3]);
    oTarget.options[oTarget.options.length] = vOption;
  }
}

/*------------------------------------------------------------*/
/* Filters the Job field sub-category when Category changes...*/
/*------------------------------------------------------------*/
fnFilterDropdownC = function(e, obj) {
  //alert('I get called from Category and my id is: ' + obj.id);
  fnFilterDropdownList('req_jobcategory', 'req_jobsubcategory', vDropDownCategory);
}

/*------------------------------------------------------------*/
/* Filters the Job location field when Province changes...    */
/*------------------------------------------------------------*/
fnFilterDropdownP = function(e, obj) {
  //alert('I get called from Province and my id is: ' + obj.id);
  fnFilterDropdownList('req_province', 'req_location', vDropDownProvince);
}

/*------------------------------------------------------------*/
/* Specialised version of fnFilterDropdownC which is called when
/* the page loads in order to set the Sub Category to a value...
/*------------------------------------------------------------*/
function fnFilterDropdownCInitialise(vID) {
  fnFilterDropdownList('req_jobcategory', 'req_jobsubcategory', vDropDownCategory);
  var oTarget = document.getElementsByName('req_jobsubcategory')[0];
  oTarget.value = vID;
}

/*------------------------------------------------------------*/
/* Specialised version of fnFilterDropdownP which is called when
/* the page loads in order to set the Location to a value...
/*------------------------------------------------------------*/
function fnFilterDropdownPInitialise(vID) {
  fnFilterDropdownList('req_province', 'req_location', vDropDownProvince);
  var oTarget = document.getElementsByName('req_location')[0];
  oTarget.value = vID;
}

/*------------------------------------------------------------*/
/* Pass in a table name and the containing div, and the table */
/* will be skinned as a YUI table...                          */ 
/*------------------------------------------------------------*/
function fnDressTable(vContainingDiv, vTableName, vColumnSort)
{
	//var myDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get("insightRateTable"));
	var myDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get(vTableName)); 
	myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE; 
	myDataSource.responseSchema = 
	{ 
	 fields:
     [
    {key:"keyword"},
	  {key:"publisher"}, 
	  {key:"magazine"},
	  {key:"description"},
	  {key:"url"}
	 ] 
	}; 
	 
	var myColumnDefs = 
	[ 
	 {key:"keyword",     label:"Keyword"}, 
	 {key:"publisher",   label:"Media Owner",     sortable:true, formatter:myFormatLinkOwner},
	 {key:"magazine",    label:"Media Product",   sortable:true, formatter:myFormatLinkProduct},
	 {key:"description", label:"Rate Card",       sortable:true},
	 {key:"url",         label:"View",            sortable:false, formatter:myFormatLinkImagePDF}
	]; 
	
	//var myDataTable = new YAHOO.widget.DataTable("insightRateTableContainer", myColumnDefs, myDataSource, {
	var myDataTable = new YAHOO.widget.DataTable(vContainingDiv, myColumnDefs, myDataSource, {
    sortedBy:	{
      key: vColumnSort,
      dir: YAHOO.widget.DataTable.CLASS_ASC
    }
  });
}

/*------------------------------------------------------------*/
/* Pass in a table name and the containing div, and the table */
/* will be skinned as a YUI table...                          */
/*------------------------------------------------------------*/
function fnDressTableSpecial(vContainingDiv, vTableName, vColumnSort)
{
	var myDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get(vTableName));
	myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
	myDataSource.responseSchema = {
	 fields: [
    {key:"colCompany"},
	  {key:"colAdvert"},
	  {key:"colSpecial"},
	  {key:"colStart"},
	  {key:"colEnds"},
    {key:"colURL"}
	 ]
	};

	var myColumnDefs =
	[
	 {key:"colCompany", label:"Media Owner",    sortable:true,  formatter:myFormatLinkOwner},
	 {key:"colAdvert",  label:"Product",        sortable:true,  formatter:myFormatLinkProduct},
	 {key:"colSpecial", label:"Special",        sortable:true},
	 {key:"colStart",   label:"Starts",         sortable:true},
     {key:"colEnds",    label:"Ends",           sortable:true},
	 {key:"colURL",     label:"View",           sortable:false, formatter:myFormatLinkImageInfo}
	];

	//var myDataTable = new YAHOO.widget.DataTable("insightRateTableContainer", myColumnDefs, myDataSource, {
	var myDataTable = new YAHOO.widget.DataTable(vContainingDiv, myColumnDefs, myDataSource, {
    sortedBy:	{
      key: vColumnSort,
      dir: YAHOO.widget.DataTable.CLASS_ASC
    }
  });
}

/*------------------------------------------------------------*/
/* Creates a YUI pop-up panel containing text derived from an */
/* array where the index into the array is passed in as the   */
/* first parameter and the HTML element next to which the     */
/* panel should appear, is passed in as the second parameter  */
/*------------------------------------------------------------*/
/*   vKeyword: index into the array [string]                  */
/*   vContext: html element against which to bind the panel   */
/*------------------------------------------------------------*/
function displayInfo(vKeyword, vContext)
{
  // Build the context first - tl is Top Left of the panel, br is Bottom Right of the panel
	//var oContext = new Array(vContext, "tr", "br");

  // This is a jippo to get around the problem of the info button not changing on Register form
  if (vKeyword == 'companytype') {
    var oSource = document.getElementsByName('req_accounttype')[0];
    var vID     = oSource.options[oSource.selectedIndex].value;
    if (vID == 1000001) {vKeyword = 'mediatype';}
  }

	// Split up the header, content & footer
  var vContent = '';
  if (oArray[vKeyword]) {
    vContent = oArray[vKeyword];
  } else {
    vContent = "Unknown Field|Unable to find any information for this field|Unknown field type for " + vKeyword;
  }
	var vPieces  = vContent.split("|");

	// Set up the context
  //var oContext = new Array(vContext, "br", "tl", ["beforeShow"]); -- new Array NOT recommended by Crockford
  var oContext = [vContext, "br", "tl", ["beforeShow"]];

	// Instantiate a Panel - already instantiated on the main form, just set parameters here
  oPanel.cfg.setProperty("context", oContext);
  oPanel.cfg.setProperty("width", "320px");
  oPanel.cfg.setProperty("visible", false);
  oPanel.cfg.setProperty("close", true);
  oPanel.cfg.setProperty("draggable", true);
  oPanel.cfg.setProperty("constraintoviewport", true);

  // Set the various properties
  oPanel.setHeader(vPieces[0]);
  oPanel.setBody(vPieces[1]);
  oPanel.setFooter(vPieces[2]);
  //oPanel.render("container");
  oPanel.render();
  oPanel.show();
}

/*------------------------------------------------------------*/
/* Creates a YUI pop-up panel containing text derived from an */
/* information held in a YUI datatable, which is built using  */
/* YUI table "cell formatter, viz.                            */
/* myFormatLinkImageInfo: displays "i" icon                   */
/*      myFormatLinkText: displays a clickable link           */
/*------------------------------------------------------------*/
/* vDescription: info to be displayed                         */
/*     vContext: html element against which to bind the panel */
/*------------------------------------------------------------*/
function displayInfoSpecial(vDescription, vContext)
{
  // Build the context first - tl is Top Left of the panel, br is Bottom Right of the panel
	//var oContext = new Array(vContext, "br", "tl", ["beforeShow"]); -- new Array NOT recommended by Crockford
  var oContext = [vContext, "br", "tl", ["beforeShow"]];
	// Instantiate a Panel - already instantiated on the main form, just set parameters here
  oPanel.cfg.setProperty("context", oContext);
  oPanel.cfg.setProperty("width", "410px");
  oPanel.cfg.setProperty("visible", false);
  oPanel.cfg.setProperty("close", true);
  oPanel.cfg.setProperty("draggable", true);
  oPanel.cfg.setProperty("constraintoviewport", true);
  // Set the various properties
  oPanel.setHeader('Description of Special');
  oPanel.setBody(vDescription);
  oPanel.render();
  oPanel.show();
}

/*------------------------------------------------------------*/
/* Creates a YUI pop-up panel containing text derived from an */
/* array where the index into the array is passed in as the   */
/* first parameter and the HTML element next to which the     */
/* panel should appear, is passed in as the second parameter  */
/*------------------------------------------------------------*/
/*   vKeyword: index into the array [string]                  */
/*   vContext: html element against which to bind the panel   */
/*------------------------------------------------------------*/
function displayInfoAdmin(vKeyword, vContext)
{
  // Build the context first - tl is Top Left of the panel, br is Bottom Right of the panel
  //var oContext = new Array(vContext, "tr", "br"); -- new Array NOT recommended by Crockford
  var oContext = [vContext, "tr", "br"];

  // Split up the header, content & footer
  var vContent = '';
  if (oArray[vKeyword]) {
    vContent = oArray[vKeyword];
  } else {
    vContent = "Unknown Field|Unable to find any information for this field|Unknown field type";
  }

  var vPieces  = vContent.split("|");
  var vDivInfo = '<div id="info"></div>';
  var vDivWait = '<div id="busyIndicator" style="display: none; position: absolute; top: 30px; left: 155px; right: 5px;"><img height="50" width="50" src="images/loader.gif"/></div>';

  // Instantiate the Panel
  var oPanel = new YAHOO.widget.Panel("newPanel", {width:"360px", visible:false, draggable:false, close:true, context:oContext} );
  // Build the panel and render it
  oPanel.setHeader(vPieces[0] + ' [' + vPieces[3] + ']');
  oPanel.setBody(vPieces[1] + vDivInfo + vDivWait);
  oPanel.setFooter(vPieces[2]);
  oPanel.render("container");
  oPanel.show();
  // Fire the AJAX request to get the additional details
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'block');
  var vURL = 'admindetails.php?id=' + vPieces[3] + '&type=0&recipient=1';
  var transaction = YAHOO.util.Connect.asyncRequest('GET', vURL, callbackDisplayInfo, null);
}

function displayInfoAdvert(vAdID, vContext) {
  // Build the context first - tl is Top Left of the panel, br is Bottom Right of the panel
  var oContext = [vContext, "bl", "br", ["beforeShow"]];  // new Array NOT recommended by Crockford

  // Instantiate the Panel
  //var oPanel = new YAHOO.widget.Panel("newPanel", { width:"360px", visible:false, draggable:false, close:true, context:oContext } );
  // Build the panel and render it

  var vDivInfo = '<div id="info"></div>';
  var vDivWait = '<div id="busyIndicator" style="display: none; position: absolute; top: 30px; left: 155px; right: 5px;"><img height="50" width="50" src="images/loader.gif"/></div>';

// Instantiate a Panel - already instantiated on the main form, just set parameters here
  oPanel.cfg.setProperty("context", oContext);
  oPanel.cfg.setProperty("width", "320px");
  oPanel.cfg.setProperty("visible", false);
  oPanel.cfg.setProperty("close", true);
  oPanel.cfg.setProperty("draggable", true);
  oPanel.cfg.setProperty("constraintoviewport", true);

  oPanel.setHeader('Advertising Analytics');
  oPanel.setBody(vDivInfo + vDivWait);
  oPanel.setFooter('supplied by Ratecard.co.za');
  oPanel.render();
  oPanel.show();

  // Fire the AJAX request to get the additional details
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'block');
  var vURL = 'paneladvert.php?adid=' + vAdID;
  YAHOO.util.Connect.asyncRequest('GET', vURL, callbackDisplayInfoAdvert, null);
}

/*------------------------------------------------------------*/
/* Looks for specific labels in the Advanced Search screen    */
/* and toggles their values according to the value of the     */
/* FORMAT drop down list - relies on ID built during the      */
/* creation of the Advanced Search form....                   */
/*------------------------------------------------------------*/
function displaySearchLabel(e) {
  // Get the three labels
  var oLabel0 = document.getElementById('circulation');
  var oLabel1 = document.getElementById('circulationupper');
  var oLabel2 = document.getElementById('circulationlower');
  var oLabel3 = document.getElementById('circulationband');
  // Get the drop-down list [does not have an ID so have to use Name]
  var oSource = document.getElementsByName('req_format')[0];
  var vKeyword = oSource.options[oSource.selectedIndex].value;
  // Apply the appropriate values pulled from the oArraySearch array...
  //oLabel1.innerHTML = oArraySearch[vKeyword] + ' Upper:';
  //oLabel2.innerHTML = oArraySearch[vKeyword] + ' Lower:';
  //oLabel3.innerHTML = oArraySearch[vKeyword] + ' Band:';
  if (oLabel0 !== null) {oLabel0.innerHTML = oArraySearch[vKeyword] + ':';}
  if (oLabel1 !== null) {oLabel1.innerHTML = oArraySearch[vKeyword] + ' Upper:';}
  if (oLabel2 !== null) {oLabel2.innerHTML = oArraySearch[vKeyword] + ' Lower:';}
  if (oLabel3 !== null) {oLabel3.innerHTML = oArraySearch[vKeyword] + ' Band:';}
}

/*------------------------------------------------------------*/
/* Function to swap an image based on its current state; pass */
/* in it's current state and it will be toggled...            */
/*------------------------------------------------------------*/
function swapImage(myImage, state)
{
 if (state == "minus") {
  myImage.src = "images/minus.gif";
 } else {
  myImage.src = "images/plus.gif";
 }
}

/*------------------------------------------------------------*/
/* Function to display or hide a given element; find element  */
/* by it's ID, and then set it's STYLE property...            */
/*------------------------------------------------------------*/
function toggleItems(vItem, vButton)
{
  //this is the ID of the hidden item
  var myItem = document.getElementById(vItem);

  //this is the ID of the plus/minus button image
  var myButton = document.getElementById(vButton);

  if (myItem.style.display != "none") {
    //items are currently displayed, so hide them
    myItem.style.display = "none";
    swapImage(myButton,"plus");
  } else {
    //items are currently hidden, so display them
    myItem.style.display = "block";
    swapImage(myButton,"minus");
  }
}

/*------------------------------------------------------------*/
/* Opens a new window with the following inputs & parameters  */
/*    vURL: the URL for the content                           */
/*  vWidth: the required width of the window                  */
/* vHeight: the required height of the window                 */
/* - toolbar=no                                               */
/* - location=no                                              */
/* - directories=no                                           */
/* - status=no                                                */
/* - menubar=no                                               */
/* - scrollbars=yes                                           */
/* - resizable=no                                             */
/*------------------------------------------------------------*/
function openWin(vURL, vWidth, vHeight) {
  window.open(vURL,"_blank","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, width=" + vWidth + ", height=" + vHeight);
}

var renderSpecialInPlace = function(workingDate, cell) {
	cell.innerHTML = workingDate.getDate();
	YAHOO.util.Dom.addClass(cell, "special");
	return YAHOO.widget.Calendar.STOP_RENDER;
};

var updateCalendarConfigSuccess = function(o){
  // Parse the JSON string
  var jsonString = o.responseText;
  var datez = YAHOO.lang.JSON.parse(jsonString);
  // Build the calendar's properties
  myCal.cfg.setProperty("mindate",  datez.minDate);
  myCal.cfg.setProperty("maxdate",  datez.maxDate);
  myCal.cfg.setProperty("pagedate", datez.pageDate);
  myCal.addRenderer(datez.rangeSpecials, renderSpecialInPlace);
  myCal.render();
  // Put the date range underneath the calendar
  document.getElementById('rangeContainer').innerHTML = datez.rangeDate;
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
};

var updateCalendarConfigFailure = function(o){
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
  // Advise the user that it has not worked
  //document.getElementById('info').innerHTML = 'Unable to fetch additional details for this user...!';
  alert('It failed');
};

var callbackCalendarConfig = {
  success: updateCalendarConfigSuccess,
  failure: updateCalendarConfigFailure
};

/*------------------------------------------------------------*/
/* Function which updates a calender via an AJAX call; used   */
/* whenever the User selects a different advert - an ONCHANGE */
/* event calls the new config, handled by a callback function */
/*------------------------------------------------------------*/
function updateCalendarConfig(e) {
  // Fire the AJAX request to get the additional details
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'block');
  var vURL = 'specialdetails.php?id=' + document.bookSpecial.req_adbookings.value;
  YAHOO.util.Connect.asyncRequest('GET', vURL, callbackCalendarConfig, null);
}

/*-- START: callbackSecretQuestion -------------------------------------------*/
var updateSecretQuestionSuccess = function(o){
  // Parse the JSON string
  var vQuestion = o.responseText;
  // Put the date range underneath the calendar
  document.getElementById('questionContainer').innerHTML = vQuestion;
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
};

var updateSecretQuestionFailure = function(o){
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
  // Advise the user that it has not worked
  //document.getElementById('info').innerHTML = 'Unable to fetch additional details for this user...!';
  alert('Unable to fetch Secret Question...');
};

var callbackSecretQuestion = {
  success: updateSecretQuestionSuccess,
  failure: updateSecretQuestionFailure
};
/*-- STOP: callbackSecretQuestion --------------------------------------------*/

/*------------------------------------------------------------*/
/* Function which uses an email address to fetch the secret   */
/* questio - an ONCHANGE event on the email address field     */
/* calls function, processed by a callback function...        */
/*------------------------------------------------------------*/
function updateSecretQuestion(e) {
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'block');
  var vURL = 'getsecretquestion.php?email=' + document.sendPassword.req_email.value;
  YAHOO.util.Connect.asyncRequest('GET', vURL, callbackSecretQuestion, null);
}

/*-- START: callbackViewAllDetails -------------------------------------------*/
var updateViewAllDetailsSuccess = function(o){
  // Parse the JSON string
  var vDetails = o.responseText;
  // Put the date range underneath the calendar
  document.getElementById('viewDetails').innerHTML = vDetails;
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
};

var updateViewAllDetailsFailure = function(o){
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
  // Advise the user that it has not worked
  //document.getElementById('info').innerHTML = 'Unable to fetch additional details for this user...!';
  alert('Unable to fetch "View All" details...');
};

var callbackViewAllDetails = {
  success: updateViewAllDetailsSuccess,
  failure: updateViewAllDetailsFailure
};
/*-- STOP:  callbackViewAllDetails -------------------------------------------*/

/*-- START: callbackViewAllJobDetails ----------------------------------------*/
var updateViewAllJobDetailsSuccess = function(o){
  // Parse the JSON string
  var vDetails = o.responseText;
  // Put the date range underneath the calendar
  document.getElementById('sectiontop').innerHTML = vDetails;
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
};

var updateViewAllJobDetailsFailure = function(o){
  // Turn off the display of the busy indicator
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'none');
  // Advise the user that it has not worked
  document.getElementById('sectiontop').innerHTML = 'Unable to fetch Job details...!';
};

var callbackViewAllJobDetails = {
  success: updateViewAllJobDetailsSuccess,
  failure: updateViewAllJobDetailsFailure
};
/*-- STOP:  callbackViewAllDetails -------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* Function used on the View All pop-up to fetch the actual additional detail */
/* of the menu item that was clicked - processed by a callback function...    */
/* p_oValue is my object passed into the menu item during buildList           */
/*----------------------------------------------------------------------------*/
function updateViewAllDetails(p_sType, p_aArgs, p_oValue) {
  // Turn off the display of 'sectiontop'
  oTarget = document.getElementById('sectiontop');
  if (oTarget) {
    oTarget.style.display = "none";
  }
  
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'block');
  vArray = p_oValue;
  var vURL = 'getviewalldetails.php?typeid=' + vArray[0] + '&uniqueid=' + vArray[1] + '&pageid=' + vArray[2] + '&groupid=' + vArray[3] + '&header=' + vArray[4];
  YAHOO.util.Connect.asyncRequest('GET', vURL, callbackViewAllDetails, null);
 }

/*----------------------------------------------------------------------------*/
/* Function used to populate the actual Job Details inside the Top Section,   */ 
/* which is also toggled on/off...                                            */
/*----------------------------------------------------------------------------*/
function updateViewAllJobDetails(vJobID) {
  YAHOO.util.Dom.setStyle('busyIndicator', 'display', 'block');
  //vArray = p_oValue;
  var vURL = 'getviewalljobdetails.php?jobid=' + vJobID;
  YAHOO.util.Connect.asyncRequest('GET', vURL, callbackViewAllJobDetails, null);

  // Turn on the display of 'sectiontop'
  oTarget = document.getElementById('sectiontop');
  oTarget.style.display = "block";
 }


/*------------------------------------------------------------*/
/* Called from the Advanced Search form and allows you to     */
/* reset all fields to their default value...                 */
/*------------------------------------------------------------*/
function fnDressSearchForm() {
  document.advancedSearch.req_language.options.selectedIndex = 0;
  document.advancedSearch.req_lsmlower.options.selectedIndex = 0;
  document.advancedSearch.req_lsmupper.options.selectedIndex = 0;
  document.advancedSearch.req_gender.options.selectedIndex = 0;
  document.advancedSearch.req_content.options.selectedIndex = 0;
  document.advancedSearch.req_footprint.options.selectedIndex = 0;
  document.advancedSearch.req_format.options.selectedIndex = 0;
  document.advancedSearch.req_frequency.options.selectedIndex = 0;
  document.advancedSearch.req_circulationsource.options.selectedIndex = 0;
  document.advancedSearch.circupper.value = '';
  document.advancedSearch.circlower.value = '';
  document.advancedSearch.search_word.value = '';
}

/*------------------------------------------------------------*/
/* Function to add seperators to a number e.g.                */
/* 12345678 => 12,345,678                                     */
/* http://www.mredkj.com/javascript/nfbasic.html              */
/*------------------------------------------------------------*/
function addCommas(nStr)
{
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}

/*----------------------------------------------------------------------------*/
/* Function used on the View All pop-up to build the items which are going to */
/* appear on the menu, after selecting from the drop down list...             */
/* vID refers to the Unique ID from the drop down list                        */
/* vPageID refers to the calling popup i.e. Directory or Jobs & it was added  */
/* so that we can use the SAME code for both popups!                          */
/*----------------------------------------------------------------------------*/
function buildList(vID, vPageID) {
  // Turn off the display of 'sectiontop'
  oTarget = document.getElementById('sectiontop');
  if (oTarget) {
    oTarget.style.display = "none";
  }

  // Work out which object to use
  var oOptions = fetchDropdownValues(vID, vPageID);

  // Clear any existing menu items
  oMenu.clearContent();
  var vSubs = false;

  // Iterate through the JSON object, building the menu items
  for (var i=0; i<oOptions.Items.length; i++) {
    vArray = oOptions.Items[i];
    // Strip out the square brackets & the count
    var vHeader = vArray[1].substr(0, vArray[1].indexOf('[', 0));

    // Do this only if it's a category/Province, and it needs to be grouped by SubCategory/City'
    if (vPageID ==2) {
      if ((vID == 1000001) || (vID == 1000002)) {
        //Advise that we DO have sub menus
        vSubs = true;

        // Parse the JSON object for the Province/City details
        switch (vID) {
          case '1000001':oItems  = YAHOO.lang.JSON.parse(typeCategoryDetail);break;
          case '1000002':oItems  = YAHOO.lang.JSON.parse(typeProvinceDetail);break;
        }
        
        vItemID = 'ID' + vArray[0];
        vItems  = oItems[vItemID];  // array of arrays

        if (vItems) {
          // Start an empty array for the itemdata
          var vSubMenuItems = [];
          // Iterate through the values of the parent array
          for (var j=0; j<vItems.length; j++) {
           vSubItems = vItems[j];
           // Strip out the square brackets & the count
           var vFooter = vSubItems[1].substr(0, vSubItems[1].indexOf('[', 0));
           //WANT THIS: var vBit  = '{text: "' + vSubItems[1] + '", onclick: {fn: showAlert(' + vSubItems[0] + ')}}';
           var vItem        = {};
           var vClick       = {};
           vClick.fn        = updateViewAllDetails;
           vClick.obj       = [vID, vArray[0], vPageID, vSubItems[0], vHeader + '-> ' + vFooter];
           vItem.text       = vSubItems[1];
           vItem.onclick    = vClick;
           vSubMenuItems[j] = vItem;
          }
        }
      }
    }

    // Build the actual menu
    if (vSubs) {
      oSubMenu = {id: 'menu'+ vArray[0] + '_' + i, itemdata: vSubMenuItems};
      oMenu.addItem({text: vArray[1], onclick: {fn: updateViewAllDetails, obj: [vID, vArray[0], vPageID, 0, vHeader]}, submenu: oSubMenu});
    } else {
      oMenu.addItem({text: vArray[1], onclick: {fn: updateViewAllDetails, obj: [vID, vArray[0], vPageID, 0, vHeader]}});
    }
  }

  // Render the menu
  oMenu.render();
}

/*----------------------------------------------------------------------------*/
/* Function used to work out which Javascript object should be parsed to get  */
/* the values which should be displayed in the menu - note that Page 1 is the */
/* "Directory" popup while Page 2 is the "Jobs" popup...                      */
/*----------------------------------------------------------------------------*/
function fetchDropdownValues(vID, vPageID) {
  // Work out which object to use
  switch(vPageID) {
    case '1':
      switch(vID) {
        case '1000000':oOptions = YAHOO.lang.JSON.parse(typeAlphabet);break;
        case '1000001':oOptions = YAHOO.lang.JSON.parse(typeMedia);break;
        case '1000002':oOptions = YAHOO.lang.JSON.parse(typeCategory);break;
        case '1000003':oOptions = YAHOO.lang.JSON.parse(typeFormat);break;
        case '1000004':oOptions = YAHOO.lang.JSON.parse(typeFootprint);break;
        case '1000005':oOptions = YAHOO.lang.JSON.parse(typeContent);break;
        case '1000006':oOptions = YAHOO.lang.JSON.parse(typeGender);break;
        case '1000007':oOptions = YAHOO.lang.JSON.parse(typeLanguage);break;
        case '1000008':oOptions = YAHOO.lang.JSON.parse(typeFrequency);break;
      }
      break;
    case '2':
      switch(vID) {
        case '1000001':oOptions = YAHOO.lang.JSON.parse(typeCategory);break;
        case '1000002':oOptions = YAHOO.lang.JSON.parse(typeProvince);break;
        case '1000003':oOptions = YAHOO.lang.JSON.parse(typeLocation);break;
        case '1000004':oOptions = YAHOO.lang.JSON.parse(typeJobType);break;
      }
      break;
  }

  // Send the value back
  return oOptions;
}

/*----------------------------------------------------------------------------*/
/* Function used to handle the mouseover event on the Index page - makes use  */
/* DELEGATION to have a single handler for ALL the rows...                    */
/*----------------------------------------------------------------------------*/
function handleIndexMouseOver(e) {
  // All the rows have an id of rowx where x= row number so we use RegEx to check
  // if the row's id starts with "ROW" - if it does, we need to do something...
  var vPattern = /^ROW/;

  // Now we need to get hold of the element that fired the mouseover
  var elTarget = YAHOO.util.Event.getTarget(e);
    //
  // Now walk up the DOM while we are inside 'sectionfight & if we find a
  // matching node, then execute the code...
  while (elTarget.id != "sectionright") {
    if (vPattern.test(elTarget.id.toUpperCase())) {
	  elTarget.style.backgroundColor = '#E49602';
	  break;
	} else {
      // Step up to the parent node
	  elTarget = elTarget.parentNode;
	}
  }
}

/*----------------------------------------------------------------------------*/
/* Function used to handle the mouseover event on the Index page - makes use  */
/* DELEGATION to have a single handler for ALL the rows...                    */
/*----------------------------------------------------------------------------*/
function handleIndexMouseOut(e) {
  // All the rows have an id of rowx where x= row number so we use RegEx to check
  // if the row's id starts with "ROW" - if it does, we need to do something...
  var vPattern = /^ROW/;

  // Now we need to get hold of the element that fired the mouseover
  var elTarget = YAHOO.util.Event.getTarget(e);
    //
  // Now walk up the DOM while we are inside 'sectionfight & if we find a
  // matching node, then execute the code...
  while (elTarget.id != "sectionright") {
    if (vPattern.test(elTarget.id.toUpperCase())) {
	  elTarget.style.backgroundColor = '';
	  break;
	} else {
      // Step up to the parent node
	  elTarget = elTarget.parentNode;
	}
  }
}

