var g_request = null;
var g_current_page = "about";

// key: anchor tag / descriptive name for page. This is a global since it's dynamic; wordpress
// pages can be added to this object and 
// value: array [0]: tab number, 
//              [1]: whether the page should be cached (i.e. contains static content)
//              [2]: web page URL
//              [3]: custom response handler after loading page
var g_pages = {
  "about":           [1, true,  "pages/page_index.php"],
  "browser_support": [1, true,  "pages/page_browsers.php"],
  "scripts_used":    [1, true,  "pages/page_scripts_used.php"],
  "contact_us":      [1, true,  "pages/page_contact_us.php", loadContactUsPageResponse],
  "generator":       [2, false, "pages/page_generate.php"],
  "download":        [3, true,  "pages/page_download.php"],
  "gnu_license":     [3, true,  "pages/page_license.php"],
  "donate":          [4, true,  "pages/page_donate.php"],
  "donate2":         [4, true,  "pages/page_donate2.php"],
  "donate_success":  [4, false, "pages/page_donate_success.php"],
  "donate_cancel":   [4, true,  "pages/page_donate_cancel.php"],
  "account":         [5, false, "pages/page_account.php"],
  "forgot_password": [5, false, "pages/page_forgot_password.php"]
}

function httpRequest(_1,_2,_3,_4){
if(window.XMLHttpRequest){
g_request=new XMLHttpRequest();
}else{
if(window.ActiveXObject){
g_request=new ActiveXObject("Msxml2.XMLHTTP");
if(!g_request){
g_request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
}
if(g_request){
if(_1.toLowerCase()!="post"){
initReq(_1,_2,_3,_4);
}else{
var _5=arguments[4];
if(_5!=null&&_5.length>0){
initReq(_1,_2,_3,_4,_5);
}
}
}else{
alert("Sorry, your browser looks pretty old, so this site won't function "+"properly for you. Time to upgrade... - or send us a nasty note "+"telling us there's a bug with the site.");
}
}

function initReq(reqType, url, bool, responseHandle)
{
  try
  {
    // specify the function that will handle the HTTP response
    g_request.onreadystatechange = responseHandle;
    g_request.open(reqType, url, bool);

    if (reqType.toLowerCase() == "post")
    {
      g_request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset:UTF-8");
      g_request.send(arguments[4]);
    }
    else
    {
      g_request.send(null);
    }
  }
  catch (errv)
  {
	  // need to update
    alert("The application cannot contact the server at this moment. Please wait and try again.");
  }
}


// onload handler for main page. Inits the RSH history object and loads the appropriate page (from
// query string)
function onPageLoad()
{
  dhtmlHistory.initialize();
  dhtmlHistory.addListener(handleHistoryChange);

	var initialLocation = dhtmlHistory.getCurrentLocation();
  updateUI(initialLocation, null);
}


function selectPage(page)
{
  // request type (POST/GET)default page and Ajax response handler 
  var requestType = "post";
  var default_page = "pages/page_index.php";
  responseFunction = loadPageResponse;

  // if page begins with wordpress_, the user wants to read a Wordpress article, view a Wordpress
  // category, or view all articles
  if (page.match(/^wordpress_/))
  {
  	requestType = "get";     
    var parts = page.split("_");

    // if it's a category
    if      (parts[1].match(/^cat/))
    {
      var category_id = parts[1].substring(3);
      url = "http://www.generatedata.com/wordpress/?cat=" + category_id;
    }
    else if (parts[1].match(/^all$/))
    {
      url = "http://www.generatedata.com/wordpress";
    }
    else
    {
      var wordpress_id = parts[1];
      url = "http://www.generatedata.com/wordpress/?p=" + wordpress_id;
    }

    var cache = true;
    if (parts.length > 2)
      cache = false;

    g_pages[page] = [1, cache, url]; 
  }

	// find out which URL we're going to load 
	var url = (g_pages[page]) ? g_pages[page][2] : default_page;

	// set the response handler for cached/static pages
	if (g_pages[page][1])
	  responseFunction = loadCachePageResponse;

	// if a specific response handler is mentioned, use that instead.
	if (g_pages[page][3])
	  responseFunction = g_pages[page][3];

  // store the page for google tracking
  pageTracker._trackPageview(page);

  // keep track of this page in memory for the browser's BACK button
  dhtmlHistory.add(page, page);

  // update the current page and keep track of the last one
  var old_page = g_current_page;
  g_current_page = page;


	// update the selected tab
  if (g_pages[g_current_page][0] == 5)
  {
  	$("tab" + g_pages[old_page][0]).src = "images/tab" + g_pages[old_page][0] + "_unselected.jpg";

    if (g_logged_in)
			$("tab5").src = "images/tab5_selected_logged_in.jpg";    
    else
			$("tab5").src = "images/tab5_selected.jpg";
  }
  else
  {
    if (g_logged_in && g_pages[old_page][0] == 5)
      $("tab5").src = "images/tab5_unselected_logged_in.jpg";
    else
      $("tab" + g_pages[old_page][0]).src = "images/tab" + g_pages[old_page][0] + "_unselected.jpg";

    $("tab" + g_pages[g_current_page][0]).src = "images/tab" + g_pages[g_current_page][0] + "_selected.jpg";
  }


  // if this is a static page and already stored in cache, load it from there instead of the server 
  if (g_pages[g_current_page][1] && historyStorage.hasKey(g_current_page + "_HTML"))
	{
	  $("content").innerHTML = historyStorage.get(g_current_page + "_HTML");
    
    if ($("ivy_fixed_bottom").style.display == "none")
      $("ivy_fixed_bottom").style.display = "block";
	}
	else
	{
	  // show the "loading" animated gif
    start_processing();

    // get the page
		var data = "a=1"; // for IE
    httpRequest("post", url, true, responseFunction, data);
  }

  return false;
}


function loadPageResponse()
{  
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      var rawResponse  = g_request.responseText;
      $("content").innerHTML = rawResponse;

      // if this was the generate tab, load 'er up!
			if (g_current_page == "generator")
      {
			  g_numRows = 0;
			  addRows('5'); 
        initializePostits(); 
        initResultType();

				if (g_logged_in)
				  $("save_form_name").value = g_default_save_form_empty_str;
      }

      if ($("ivy_fixed_bottom").style.display == "none")
        $("ivy_fixed_bottom").style.display = "block";
      
      end_processing();
    }
    else
      alert(g_request.status);
  }
}


function loadCachePageResponse()
{  
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      var rawResponse  = g_request.responseText;
      $("content").innerHTML = rawResponse;
			historyStorage.put(g_current_page + "_HTML", rawResponse);
    
      if ($("ivy_fixed_bottom").style.display == "none")
        $("ivy_fixed_bottom").style.display = "block";
      
      end_processing();
    }
    else
      alert(g_request.status);
  }
}


function loadContactUsPageResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      var rawResponse  = g_request.responseText;
      $("content").innerHTML = rawResponse;
			historyStorage.put("contact_us_HTML", rawResponse);
      document.contact_form.name.focus();

      end_processing();
    }
  }
}


/** This function is called whenever the user presses the back or forward buttons. This
    function will be passed the newLocation, as well as any history data we associated with 
	the location. */
function handleHistoryChange(newLocation, historyData)
{
  updateUI(newLocation, historyData);                       
}


// A simple RSH method that updates our user interface using the new location.
// ** newLocation is any anchor tag, denoting a specific page.
function updateUI(newLocation, historyData)
{
  if (!newLocation) 
    newLocation = "about";

  selectPage(newLocation);
}


function start_processing()
{
  $("page_loading_icon").style.display = "block";
	
	// for IE...
	setTimeout('$("page_loading_icon").src="/images/loading2.gif"', 200);
}

function end_processing()
{
  $("page_loading_icon").style.display = "none";
}

// ------------------------------------------------------------------------------------------------

// login functions
function login()
{
  var url   = "global/ajax_login.php";
  var email = $("email").value;
  var password = $("password").value;
  var data = "email=" + email + "&password=" + password;

  if (email == "" || password == "")
  {
    alert("Please enter your email address and password.");
    return false;
  }
  else
  {
    start_processing();
    httpRequest("post", url, true, handleLoginResponse, data);
  }

  return false;
}


function logout()
{
  var url   = "global/ajax_logout.php";
  start_processing();
  httpRequest("get", url, true, handleLogoutResponse);
}


function handleLoginResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      end_processing();

      var rawResponse  = g_request.responseText;
      var jsonResponse = eval("(" + rawResponse + ")");

      // login was successful
      if (jsonResponse.success)
      {
        g_logged_in = true;

        // update the "login" tab to show "My Account"
        $("tab5").src = "images/tab5_selected_logged_in.jpg";

        // now reload the account page
        selectPage("account");
      }
      else
      {
        $("error_message").innerHTML = "<div class='error'><span><span><span>"
          + "<span><span><span><span><span><img src='images/alert.jpg' align='left' />" + jsonResponse.message + "</span></span></span></span></span></span></span></span></div>";
      }
    }
    else
    {
      alert("A problem occurred communicating with the XMLHttpRequest object and the server program.");
    }
  }
}


function handleLogoutResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      g_logged_in = false;

      // the user's been logged out, re-load the account/login page
      selectPage("account");
    }
  }
}


function submitContactUs(f)
{
  var url   = "/admin/process.php";

  var name = f.name.value;
  var email = f.email.value;
  var subject = f.subject.value;
  var comments = f.comments.value;
  var data = "name=" + name + "&email=" + email + "&subject=" + subject + "&comments=" + comments + "&form_tools_form_id=1";

  if (!name)
  {
    alert("Please enter your name.");
    f.name.focus();
    return false;
  }
  else if (!email)
  {
    alert("Please enter your email address.");
    f.email.focus();
    return false;
  }
  else if (!comments)
  {
    alert("Please enter your comments.");
    f.comments.focus();
    return false;
  }

  start_processing();
  httpRequest("post", url, true, handleSubmitContactUsResponse, data);

  return false;
}


function handleSubmitContactUsResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      end_processing();
      $("contact_us_form").innerHTML = g_request.responseText;
    }
    else
      alert(g_request.status);
  }
}


function submitDonateForm(f)
{
  var url   = "/admin/process.php";

  var firstname = f.firstname.value;
  var lastname = f.lastname.value;
  var email = f.email.value;
  var location = f.location.value;
  var country = f.country.value;
  var amount = f.amount.value;

  var data = "firstname=" + firstname + "&lastname=" + lastname + "&email=" + email + "&location=" 
	  + location + "&country=" + country + "&amount=" + amount + "&completed=no&form_tools_form_id=2";

  if (!firstname)
  {
    alert("Please enter your first name.");
    f.firstname.focus();
    return false;
  }
  else if (!lastname)
  {
    alert("Please enter your last name.");
    f.lastname.focus();
    return false;
  }
  else if (!email)
  {
    alert("Please enter your email address.");
    f.email.focus();
    return false;
  }

  start_processing();
  httpRequest("post", url, true, handleSubmitDonateFormResponse, data);

  return false;
}


function handleSubmitDonateFormResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
		  // so far so good; we've submitted the donation info to Form Tools for storage. The "thankyou"
			// page of Form Tools contains a hidden form primed for submission to PayPal. Do so!   
			$("donation_zone").innerHTML = g_request.responseText;
			end_processing();

			document.paypal_form.submit();
    }
    else
      alert(g_request.status);
  }
}


function submitCreateAccountForm(f)
{
  var url   = "/global/ajax_create_account.php";

  var password   = f.password.value;
  var password_2 = f.password_2.value;
  var password_recovery_question = f.password_recovery_question.value;
  var password_recovery_answer   = f.password_recovery_answer.value;

  var data = "password=" + password + "&password_recovery_question=" + password_recovery_question 
	  + "&password_recovery_answer=" + password_recovery_answer;

  if (!password)
  {
    alert("Please enter your password.");
    f.password.focus();
    return false;
  }
  else if (!password_2)
  {
    alert("Please re-enter your password.");
    f.password_2.focus();
    return false;
  }
  else if (password != password_2)
  {
    alert("Please ensure your passwords are the same.");
    f.password.focus();
    return false;
  }
  else if (!password_recovery_question)
  {
    alert("Please select a password recovery question.");
    f.password_recovery_question.focus();
    return false;
  }
  else if (!password_recovery_answer)
  {
    alert("Please supply an answer to the password recovery question.");
    f.password_recovery_answer.focus();
    return false;
  }

  start_processing();
  httpRequest("post", url, true, handleCreateAccountResponse, data);

  return false;
}


function handleCreateAccountResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      g_logged_in = true;

      // just redirect to the account tab
      selectPage('account');
    }
    else
      alert(g_request.status);
  }
}

function retrieve_recovery_question(f)
{
  var url   = "/global/ajax_retrieve_recovery_question.php";
  var email   = f.email.value;
  var data = "email=" + email

  if (!email)
  {
    alert("Please enter your email address.");
    f.password.focus();
    return false;
  }
  
  start_processing();
  httpRequest("post", url, true, handleRetrieveRecoveryQuestionResponse, data);

  return false;
}


function handleRetrieveRecoveryQuestionResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      end_processing();
		
      var rawResponse  = g_request.responseText;
      var jsonResponse = eval("(" + rawResponse + ")");

      // email was found. Display the recovery question.
      if (jsonResponse.success)
      {
        Effect.Appear("question_div");
        $("question").innerHTML = "<b>" + jsonResponse.question + "</b>";
        
        // if the error message div is displayed, hide it
        Effect.Fade("error_message");
      }
      else
      {
        $("question_div").style.display = "none";        
        $("error_message").style.display = "block";        
        $("error_message").innerHTML = "<div class='error'><span><span><span>"
          + "<span><span><span><span><span><img src='images/alert.jpg' align='left' />" + jsonResponse.message + "</span></span></span></span></span></span></span></span></div>";
      }
    }
    else
      alert(g_request.status);
  }
}


function check_password_recovery_answer(f)
{
  var url   = "/global/ajax_check_password_recovery_answer.php";
  var answer   = f.answer.value;
  var data = "answer=" + answer;

  if (!answer)
  {
    alert("Please enter your response.");
    f.answer.focus();
    return false;
  }

  start_processing();
  httpRequest("post", url, true, handleCheckAnswerResponse, data);

  return false;
}


function handleCheckAnswerResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      end_processing();

      var rawResponse  = g_request.responseText;
      var jsonResponse = eval("(" + rawResponse + ")");

      // email was found. Display the recovery question
      if (jsonResponse.success)
      {
        Effect.Fade("get_question");
        Effect.Fade("question_div");
        
        // if the error message div is displayed, hide it
        $("error_message").innerHTML = "<div class='error'><span><span><span>"
          + "<span><span><span><span><span>" + jsonResponse.message + "</span></span></span></span></span></span></span></span></div>";

        Effect.Appear("error_message");
      }
      else
      {
        $("error_message").style.display = "block";        
        $("error_message").innerHTML = "<div class='error'><span><span><span>"
          + "<span><span><span><span><span><img src='images/alert.jpg' align='left' />" + jsonResponse.message + "</span></span></span></span></span></span></span></span></div>";
      }      
    }
  }
}


/* JS code for the data generator */

var g_numRows = 0;
var g_countries = new Array();
var g_allCountries = new Array("canada", "netherlands", "uk", "us");
var g_lastJsonResponse;

(new Image(15,14)).src = "images/question_odd.jpg";
(new Image(15,14)).src = "images/question_even.jpg";


/*
  [0] : code to execute - (function)
	[1] : boolean test to determine completion - (function)
	[2] : interval ID (managed internally by script) - (integer)  
*/
var g_queue = new Array();
function process_queue()
{
  if (!g_queue.length)
    return;

  // if this code hasn't begun being executed, start 'er up 
  if (!g_queue[0][2])
  {
    // run the code with a 10 millisecond timeout - this appears to be unavoidable, unfortunately. 
    window.setTimeout(function() { g_queue[0][0]() }, 10);
    timeout_id = window.setInterval("check_queue_item_complete()", 50); 
    g_queue[0][2] = timeout_id;
  }
}

function check_queue_item_complete()
{
  if (g_queue[0][1]())
  {
    window.clearInterval(g_queue[0][2]);
    g_queue.shift();
    process_queue();
  }  
}


// time-consuming function. Trying new queueing mechanism... 
function changeRowType(rowType, choice)
{
  var row = rowType.replace(/^type_/, "");
  var rowType = (row%2 == 0) ? "even" : "odd";

  switch (choice)
  {
    // Human Data
    case "Name":     
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = $('HTML_Block_Name').innerHTML.replace(/\$ROW\$/g, row);
            $('options_' + row).innerHTML = "<input type='text' name='option_" + row + "' id='option_" + row + "' style='width: 230px;' />";
            $('help_' + row).innerHTML    = "<a href='#' onclick='return showPostit(\"postit1\", 3, 300, 200)'><img src='images/question_" + rowType + ".jpg' border='0'/></a>";          
          },
					function() { return (typeof $("option_" + row) != "undefined"); } 
             ] );
      break;
    case "Phone":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = $("HTML_Block_Phone").innerHTML.replace(/\$ROW\$/g, row);
            $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit2', 3, 340, 180)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";
            $('options_' + row).innerHTML = "<input type='text' name='option_" + row + "' id='option_" + row + "' style='width: 230px;' />";
          },
					function() { return (typeof $("option_" + row) != "undefined"); } 
             ] );
      break;
    case "Email":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
            $('options_' + row).innerHTML = "&nbsp;No options available.";
            $('help_' + row).innerHTML = "";
          },
					function() { return true; } 
             ] );
      break;
    case "Street-Address":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
            $('options_' + row).innerHTML = "&nbsp;No options available.";
            $('help_' + row).innerHTML    = "";
          },
					function() { return true; } 
             ] );
      break;
    case "City":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
            $('options_' + row).innerHTML = "&nbsp;No options available.";
            $('help_' + row).innerHTML    = "";
          },
					function() { return true; } 
             ] );
      break;
    case "Postal-Zip":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
            $('options_' + row).innerHTML = $("HTML_Block_Postal").innerHTML.replace(/\$ROW\$/g, row);
            $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit9', 3, 300, 80)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";
          },
          function() { return (typeof $('includeZipUS_' + row) != "undefined"); }
             ] );
      break;
    case "State-Province":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
            $('options_' + row).innerHTML = $("HTML_Block_State").innerHTML.replace(/\$ROW\$/g, row);
            $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit10', 3, 320, 150)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";
          },
          function() { return (typeof $('includeRegionUSShort_' + row) != "undefined"); }
             ] );
      break;
    case "Country":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
            $('options_' + row).innerHTML = "&nbsp;No options available.";
            $('help_' + row).innerHTML    = "";
          },
          function() { return (typeof $('includeRegionUSShort_' + row) != "undefined"); }
             ] );
      break;
    case "Date":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = $("HTML_Block_Date").innerHTML.replace(/\$ROW\$/g, row);
            $('options_' + row).innerHTML = $("HTML_Block_DateOptions").innerHTML.replace(/\$ROW\$/g, row);
            $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit11', 3, 450, 670)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";
          },
					function() { return (typeof $("option_" + row) != "undefined"); } 
             ] );
      break;

    // Text
    case "Text-Fixed":
      g_queue.push( [ 
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
            $('options_' + row).innerHTML = $("HTML_Block_Text-Fixed").innerHTML.replace(/\$ROW\$/g, row);
            $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit3', 3, 300, 120)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";						
          },
					function() { return (typeof $("numWords_" + row) != "undefined"); } 
             ] );
      break;
    case "Text-Random":
      g_queue.push( [
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
						$('options_' + row).innerHTML = $("HTML_Block_Text-Random").innerHTML.replace(/\$ROW\$/g, row);
            $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit4', 3, 300, 110)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";						
          },
					function() { return (typeof $("numWordsMax_" + row) != "undefined"); } 
             ] );
      break;

    // Custom
    case "Auto-Increment":
      g_queue.push( [
          function() {
            $('example_' + row).innerHTML = $("HTML_Block_Auto-Increment-Example").innerHTML.replace(/\$ROW\$/g, row);
            $('options_' + row).innerHTML = $("HTML_Block_Auto-Increment").innerHTML.replace(/\$ROW\$/g, row); 
            $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit12', 3, 300, 120)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";						
          },
					function() { return (typeof $("autoIncrementValue_" + row) != "undefined"); } 
             ] );
      break;
    case "Number-Range":
      g_queue.push( [
          function() {
            $('example_' + row).innerHTML = "&nbsp;No examples available.";
            $('options_' + row).innerHTML = $("HTML_Block_Number-Range").innerHTML.replace(/\$ROW\$/g, row); 
            $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit7', 3, 300, 80)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";						
          },
					function() { return (typeof $("numRangeMax_" + row) != "undefined"); } 
             ] );
      break;
    case "Alphanumeric":
      g_queue.push( [
          function() {
            $('example_' + row).innerHTML = $("HTML_Block_Alphanumeric").innerHTML.replace(/\$ROW\$/g, row);
            $('options_' + row).innerHTML = "<input type='text' name='option_" + row + "' id='option_" + row + "' style='width: 230px;' />";
			      $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit8', 3, 400, 180)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";						
          },
					function() { return (typeof $("option_" + row) != "undefined"); } 
             ] );
      break;
    case "List":
      g_queue.push( [
          function() {
            $('example_' + row).innerHTML = $("HTML_Block_CustomListExamples").innerHTML.replace(/\$ROW\$/g, row);
            $('options_' + row).innerHTML = $("HTML_Block_List").innerHTML.replace(/\$ROW\$/g, row);
			      $('help_' + row).innerHTML    = "<a href='#' onclick=\"return showPostit('postit6', 3, 300, 110)\"><img src='images/question_" + rowType + ".jpg' border='0'/></a>";						
          },
					function() { return (typeof $("option_" + row) != "undefined"); } 
             ] );
      break;

    default:
      g_queue.push( [
          function() {
            $('example_' + row).innerHTML = "";
            $('options_' + row).innerHTML = "";
			      $('help_' + row).innerHTML    = "";						
          },
					function() { return true; } 
             ] );
      break;
  }

  process_queue();	
}


function addRows(numRows)
{
  // check numRows is an integer
  if (numRows.match(/\D/) || numRows == 0 || numRows == "")
  {
    alert("Please enter the number of rows to add.");
    document.data.numRows.focus();
    return;
  }

  // get the current table
  var tbody = $("dataTable").getElementsByTagName("tbody")[0];

  for (var i=1; i<=numRows; i++)
  {
    var currRow = ++g_numRows;
    var rowClass = (currRow%2 == 0) ? "evenRow" : "oddRow";

    var row = document.createElement("tr");
    row.setAttribute("class", rowClass); // for Firefox
    row.className = rowClass;            // for IE

    // [1] first cell: row number
    var td1 = document.createElement("td");
    td1.setAttribute("align", "center");
    td1.appendChild(document.createTextNode(currRow));

    // [2] second <td> cell: "title" input field
    var td2 = document.createElement("td");
    var title = document.createElement("input");
    title.setAttribute("type", "text");
    title.setAttribute("name", "title_" + currRow);
    title.setAttribute("id", "title_" + currRow);
    title.setAttribute("style", "width: 130px;");
    td2.appendChild(title);

    // [3] <td> cell: data type dropdown
    var td3 = document.createElement("td");
    var dataTypeDropdown = document.createElement("select");
    dataTypeDropdown.setAttribute("name", "type_" + currRow);
    dataTypeDropdown.setAttribute("id", "type_" + currRow);
    dataTypeDropdown.onchange = function (evt) { changeRowType(this.name, this.value) };

    var option1 = document.createElement("option");
    option1.setAttribute("value", "");
    option1.appendChild(document.createTextNode("Please Select"));

    dataTypeDropdown.appendChild(option1);  

    // opgroup 1: human data
    var optgroup1 = document.createElement("optgroup");
    optgroup1.setAttribute("label", "Human Data");

    var option2 = document.createElement("option");
    option2.setAttribute("value", "Name");
    option2.appendChild(document.createTextNode("Name"));
    var option3 = document.createElement("option");
    option3.setAttribute("value", "Phone");
    option3.appendChild(document.createTextNode("Phone/Fax"));   
    var option4 = document.createElement("option");
    option4.setAttribute("value", "Email");
    option4.appendChild(document.createTextNode("Email"));

    var option14 = document.createElement("option");
    option14.setAttribute("value", "Street-Address");
    option14.appendChild(document.createTextNode("Street Address"));
    var option15 = document.createElement("option");
    option15.setAttribute("value", "City");
    option15.appendChild(document.createTextNode("City"));

    var option5 = document.createElement("option");
    option5.setAttribute("value", "Postal-Zip");
    option5.appendChild(document.createTextNode("Postal / Zip"));
    var option6 = document.createElement("option");
    option6.setAttribute("value", "State-Province");
    option6.appendChild(document.createTextNode("State / Province / County"));
    var option7 = document.createElement("option");
    option7.setAttribute("value", "Country");
    option7.appendChild(document.createTextNode("Country"));
    var option8 = document.createElement("option");
    option8.setAttribute("value", "Date");
    option8.appendChild(document.createTextNode("Date"));

    // add the options to the optgroup
    optgroup1.appendChild(option2);
    optgroup1.appendChild(option3);
    optgroup1.appendChild(option4);
    optgroup1.appendChild(option14);
    optgroup1.appendChild(option15);
    optgroup1.appendChild(option5);
    optgroup1.appendChild(option6);
    optgroup1.appendChild(option7);
    optgroup1.appendChild(option8);

    // opgroup 2: text data
    var optgroup2 = document.createElement("optgroup");
    optgroup2.setAttribute("label", "Text");

    var option9 = document.createElement("option");
    option9.setAttribute("value", "Text-Fixed");
    option9.appendChild(document.createTextNode("Fixed Number of Words"));
    var option10 = document.createElement("option");
    option10.setAttribute("value", "Text-Random");
    option10.appendChild(document.createTextNode("Random Number of Words"));

    // add the options to the optgroup
    optgroup2.appendChild(option9);
    optgroup2.appendChild(option10);


    // opgroup 3: custom field 
    var optgroup3 = document.createElement("optgroup");
    optgroup3.setAttribute("label", "Custom");

    var option16 = document.createElement("option");
    option16.setAttribute("value", "Auto-Increment");
    option16.appendChild(document.createTextNode("Auto-increment"));   
    var option11 = document.createElement("option");
    option11.setAttribute("value", "Number-Range");
    option11.appendChild(document.createTextNode("Number Range"));   
    var option12 = document.createElement("option");
    option12.setAttribute("value", "Alphanumeric");
    option12.appendChild(document.createTextNode("Alpha-numeric"));
    var option13 = document.createElement("option");
    option13.setAttribute("value", "List");
    option13.appendChild(document.createTextNode("Custom List"));

    // add the options to the optgroup
    optgroup3.appendChild(option16);
    optgroup3.appendChild(option11);
    optgroup3.appendChild(option12);
    optgroup3.appendChild(option13);

    // add the optgroups to the select box
    dataTypeDropdown.appendChild(optgroup1);
    dataTypeDropdown.appendChild(optgroup2);
    dataTypeDropdown.appendChild(optgroup3);
 
    // and, complete the td cell by adding the entire dropdown
    td3.appendChild(dataTypeDropdown);

    // [4] fourth <td> cell: example
    var td4 = document.createElement("td");
    var exampleDiv = document.createElement("div");
    exampleDiv.setAttribute("id", "example_" + currRow);
    td4.appendChild(exampleDiv);

    // [5] fifth <td> cell: options 
    var td5 = document.createElement("td");
    td5.setAttribute("id", "options_" + currRow);
    var optionsDiv = document.createElement("div");
    optionsDiv.setAttribute("id", "options_" + currRow);
    td5.appendChild(optionsDiv);

    // [6] sixth <td> cell: help
    var td6 = document.createElement("td");
    td6.setAttribute("align", "center");
    var helpDiv = document.createElement("div");
    helpDiv.setAttribute("id", "help_" + currRow);
    td6.appendChild(helpDiv);

    // add the table data cells to the row
    row.appendChild(td1);
    row.appendChild(td2);
    row.appendChild(td3);
    row.appendChild(td4);
    row.appendChild(td5);
    row.appendChild(td6);

    // add the row to the table
    tbody.appendChild(row);
  }

  // update the number of columns
  $("numCols").value = g_numRows;  
}


function empty_form(require_confirmation, num_init_rows)
{
  if (require_confirmation)
  {
    var answer = confirm("Are you sure you want to empty this form?");    
    if (!answer)
      return;
  }

  // empty the main form
  g_numRows = 0;
  var form_table = $("dataTable");
  while (form_table.rows.length > 1) 
    form_table.deleteRow(form_table.rows.length-1);
    
  if (num_init_rows)
    addRows(num_init_rows);
}


// determines the target of the form: the hidden iframe for excel or a new window for HTML
function submitForm()
{
  numResults = $("numResults").value;
  numCols    = $("numCols").value;
  
  // check numResults is an integer
  if (numResults.match(/\D/) || numResults == 0 || numResults == "" || numResults > 5000)
  {
    alert("Please enter a valid number of results (must be under 5000!)");
    $("numResults").focus();
    return false;
  }

  // XML
  var error = false;
  if (document.data.resultType[2].checked)
  {
    var nodeNum = 1;
    for (nodeNum=1; nodeNum<=numCols; nodeNum++)
    {
      if (!$("title_" + nodeNum).value && $("type_" + nodeNum).value != "")
      {
        alert("Please enter every node name.");
        $("title_" + nodeNum).focus();
        error = true;
        break;
      }
      else if ($("title_" + nodeNum).value.match(/\W/))
      {
        alert("XML node names can only alphanumeric characters and must begin with a letter.");
        $("title_" + nodeNum).focus();
        error = true;
        break;
      }
    }
  }  
  if (document.data.resultType[4].checked)
  {
    var nodeNum = 1;
    for (nodeNum=1; nodeNum<=numCols; nodeNum++)
    {
      if (!$("title_" + nodeNum).value && $("type_" + nodeNum).value != "")
      {
        alert("Please enter every column name.");
        $("title_" + nodeNum).focus();
        error = true;
        break;
      }
      else if ($("title_" + nodeNum).value.match(/\W/))
      {
        alert("Database column names can only alphanumeric characters and must begin with a letter.");
        $("title_" + nodeNum).focus();
        error = true;
        break;
      }
    }
  }  
  
  if (error)
    return false;


  // all checks out, set the form target 
  if (document.data.resultType[0].checked)
    document.data.target = "_blank";
  else if (document.data.resultType[1].checked)
    document.data.target = "hiddenIframe";      
  else if (document.data.resultType[2].checked)
    document.data.target = "_blank";
  else if (document.data.resultType[3].checked)
    document.data.target = "hiddenIframe";
  else if (document.data.resultType[4].checked)
    document.data.target = "_blank";

  return true;
}


// optionType: State, Province, County
function hideShowStateProvCounty(row, isChecked, country)
{
  if (isChecked)
  {
    var ch1 = $("includeRegion" + country + "Full_" + row);
    ch1.disabled = false;
    var label1 = $("includeRegion" + country + "FullLabel_" + row);
    label1.className = "suboptionActive";

    var ch2 = $("includeRegion" + country + "Short_" + row);
    ch2.disabled = false;
    var label1 = $("includeRegion" + country + "ShortLabel_" + row);
    label1.className = "suboptionActive";
  }
  else
  {
    var ch1 = $("includeRegion" + country + "Full_" + row);
    ch1.disabled = true;
    var label1 = $("includeRegion" + country + "FullLabel_" + row);
    label1.className = "suboptionInactive";

    var ch2 = $("includeRegion" + country + "Short_" + row);
    ch2.disabled = true;
    var label1 = $("includeRegion" + country + "ShortLabel_" + row);
    label1.className = "suboptionInactive";
  }
}


// called whenever the user changes the result type, to hide/show custom options 
function changeResultType(resultType)
{
  switch (resultType)
	{
	  case "HTML":
	  case "Excel":
		  $("custom_col_name").innerHTML = "Column Title";
		  $("sql_options").style.display = "none";
		  $("xml_options").style.display = "none";			
		  $("csv_options").style.display = "none";
		  break;
	  case "XML":
		  $("custom_col_name").innerHTML = "Node Name";
		  $("sql_options").style.display = "none";
		  $("xml_options").style.display = "block";			
		  $("csv_options").style.display = "none";
		  break;
	  case "CSV":
		  $("custom_col_name").innerHTML = "Column Title";
		  $("sql_options").style.display = "none";
		  $("xml_options").style.display = "none";			
		  $("csv_options").style.display = "block";
		  break;			
	  case "SQL":		
		  $("custom_col_name").innerHTML = "Table Column";
		  $("sql_options").style.display = "block";
		  $("xml_options").style.display = "none";
		  $("csv_options").style.display = "none";
		  break;			
	}
}

function selectDatabaseType(choice)
{
  if (choice == "MySQL")
  {
    $("enclose_with_backquotes").disabled = false;
  }
  if (choice == "Oracle")
  {
    $("enclose_with_backquotes").disabled = true;
    $("enclose_with_backquotes").checked = false;
  }
}


// called on page load. Hides/shows the resultType-specific box
function initResultType()
{
  for (i=0;i<document.data.resultType.length; i++)
	{
	  if (document.data.resultType[i].checked)
		{
		  switch (document.data.resultType[i].value)
			{
			  case "XML":
		      $("custom_col_name").innerHTML = "Node Name";
		      $("xml_options").style.display = "block";
				  break;
			  case "SQL":
		      $("custom_col_name").innerHTML = "Table Column";
  		    $("sql_options").style.display = "block";
				  break;
			  case "CSV":
		      $("custom_col_name").innerHTML = "Table Column";
		      $("csv_options").style.display = "block";
				  break;
		  }
		}
	}
}


function updateCountryChoice()
{
  // empty g_countries
	g_countries.length = 0;

	for (i=0; i<document.data["countryChoice[]"].length; i++)
	{
	  if (document.data["countryChoice[]"][i].checked)
		  g_countries.push(document.data["countryChoice[]"][i].value);
	}

	// now hide/show all country-specific elements, based on what the user has selected)	
	for (i=0; i<g_allCountries.length; i++)
	{
    var elements = $$('div.country_' + g_allCountries[i]);

		// if selected, ensure that elements with that language's classes are visible
		if (g_countries.contains(g_allCountries[i]))
		  display = "block";
	  else
		  display = "none";

  	if (elements.length > 0)
    {
  		for (k=0; k<elements.length; k++)
  		  elements[k].style.display = display;
  	}
	}
}


function save_form()
{
  var buttons = new Array();

  // check there's a name specified
  var new_form_name = $("save_form_name").value;

  if (!new_form_name || new_form_name == g_default_save_form_empty_str)
  {
    buttons.push('<input type="button" name="" value="OK" onclick="hide_message()" />');
	  display_message("error", "Please enter a form name.", buttons);
		return;
  }

  // if the name already exists, check with the user that it's okay to overwrite it
  var form_exists = false;
  var form_list_dd = $("form_list"); 
  for (i=0; i<form_list_dd.length; i++)
  {
    if (form_list_dd[i].text == new_form_name)
      form_exists = true;
  }

	if (form_exists)
	{
  	buttons.push('<input type="button" name="" value="Yes" onclick="save_form_confirm()" />'); 
  	buttons.push('<input type="button" name="" value="No" onclick="hide_message()" />');
    display_message("error", "This form already exists. Do you want to overwrite it?", buttons);
		return false;	
  }

	save_form_confirm();
}


function save_form_confirm()
{  
  // okay! now we serialize the form data and submit it for storage [note, no cross-browser innerHTML 
  // solution currently works, so we're forced to do this manually, which is a PAIN].
  var url = "global/ajax_save.php";

  var serialized = new Array();
	for (row=1; row<=g_numRows; row++)
	{
    // note: we save ALL rows, even the empty ones. Maybe the user wanted to have an empty row
	  var rowComponents = new Array();
    rowComponents.push("title" + row + ": \"" + encodeURIComponent($("title_" + row).value) + "\"");
    rowComponents.push("type" + row + ": \"" + encodeURIComponent($("type_" + row).value) + "\"");

    var example = "";
    var options = "";
    switch ($("type_" + row).value)
    {
      case "Name":
      case "Phone":
      case "Alphanumeric":
        example = encodeURIComponent(document.data["datatype_" + row].value);
        options = encodeURIComponent(document.data["option_" + row].value);
        break;
      case "Postal-Zip":
        var zips = new Array();
        if ($("includeZipCanada_" + row).checked)      zips.push("canada");
        if ($("includeZipNetherlands_" + row).checked) zips.push("netherlands");
        if ($("includeZipUK_" + row).checked)          zips.push("uk");
        if ($("includeZipUS_" + row).checked)          zips.push("us");
        options = zips.join(",");
        break;
      case "State-Province":
			  var info = new Array();
        if ($("includeRegionCanada_" + row).checked)      info.push("canada");
        if ($("includeRegionCanadaFull_" + row).checked)  info.push("canada_full");
        if ($("includeRegionCanadaShort_" + row).checked) info.push("canada_short");
        if ($("includeRegionNetherlands_" + row).checked)      info.push("netherlands");
        if ($("includeRegionNetherlandsFull_" + row).checked)  info.push("netherlands_full");
        if ($("includeRegionNetherlandsShort_" + row).checked) info.push("netherlands_short");
        if ($("includeRegionUK_" + row).checked)      info.push("uk");
        if ($("includeRegionUKFull_" + row).checked)  info.push("uk_full");
        if ($("includeRegionUKShort_" + row).checked) info.push("uk_short");
        if ($("includeRegionUS_" + row).checked)      info.push("us");
        if ($("includeRegionUSFull_" + row).checked)  info.push("us_full");
        if ($("includeRegionUSShort_" + row).checked) info.push("us_short");
        options = info.join(",");
			  break;
			case "Date":
        options = encodeURIComponent($("fromDate_" + row).value + "," + $("toDate_" + row).value + "," + $("option_" + row).value); 
			  break;
      case "Text-Fixed":
        options = encodeURIComponent($("numWords_" + row).value); 
			  break;
      case "Text-Random":
			  is_checked = ($("startsWithLipsum_" + row).checked) ? "true" : "false";
        options = encodeURIComponent(is_checked + "," + $("numWordsMin_" + row).value + "," + $("numWordsMax_" + row).value);
			  break;
      case "Auto-Increment":
        example = encodeURIComponent(document.data["datatype_" + row].value);
        options = encodeURIComponent($("autoIncrementStart_" + row).value + "," + $("autoIncrementValue_" + row).value);
			  break;
		  case "Number-Range":
        options = encodeURIComponent($("numRangeMin_" + row).value + "," + $("numRangeMax_" + row).value); 
			  break;
		  case "List":
        example = encodeURIComponent(document.data["datatype_" + row].value);
				radio1 = ($("listType1_" + row).checked) ? "true" : "false";			
				radio2 = ($("listType2_" + row).checked) ? "true" : "false";
				options = encodeURIComponent(radio1 + "," + radio2 + "," +
                    $("exactly_" + row).value + "," + $("atMost_" + row).value + "," + 
                    $("option_" + row).value);
			  break;
    }

    rowComponents.push("example" + row + ": \"" + example + "\"");
    rowComponents.push("option" + row + ": \"" + options + "\"");

		rowStr = rowComponents.join(",");
		serialized.push(rowStr);
	}

  // add the other information. We send the FORM information to the server as a URL-encoded, 
	// well-formatted JSON object. This lets us simply eval() the result to access the data on reloading 
	// the form
  var num_rows    = "num_rows: " + g_numRows;
  var num_results = "num_results: " + document.data.numResults.value;
  var result_type = "result_type: \"";  
  for (i=0; i<document.data.resultType.length; i++)
  {
    if (document.data.resultType[i].checked)
      result_type += document.data.resultType[i].value;
  }
  result_type += "\"";  
  var countries = new Array();
  for (i=0; i<document.data["countryChoice[]"].length; i++)
  {
    if (document.data["countryChoice[]"][i].checked)
      countries.push(document.data["countryChoice[]"][i].value);
  }
  var countries_str = "countries: \"" + countries.join(",") + "\"";
  var xml_root_node_name   = "xml_root_node_name: \"" + encodeURIComponent(document.data.xml_root_node_name.value) + "\"";
  var xml_record_node_name = "xml_record_node_name: \"" + encodeURIComponent(document.data.xml_record_node_name.value) + "\"";
  var sql_table_name       = "sql_table_name: \"" + encodeURIComponent(document.data.sql_table_name.value) + "\"";
  var sql_database         = "sql_database: \"" + encodeURIComponent(document.data.sql_database.value) + "\"";
  var csv_delimiter        = "csv_delimiter: \"" + encodeURIComponent(document.data.csv_delimiter.value) + "\"";

  var sql_create_table_is_checked = ($("sql_create_table").checked) ? "true" : "false";
  var sql_create_table     = "sql_create_table: \"" + sql_create_table_is_checked + "\"";

  var enclose_with_backquotes_is_checked = ($("enclose_with_backquotes").checked) ? "true" : "false";
  var enclose_with_backquotes     = "enclose_with_backquotes: \"" + enclose_with_backquotes_is_checked + "\"";

  var serializedStr = encodeURIComponent(serialized.join(","));
  var post_info = "form_name=" + encodeURIComponent($("save_form_name").value)
    + "&form_content={" + serializedStr + "," + num_rows + "," + num_results + "," + result_type + ","
    + countries_str + "," + xml_root_node_name + "," + xml_record_node_name + "," + sql_table_name + ","
    + sql_create_table + "," + enclose_with_backquotes  + "," + sql_database + "," + csv_delimiter + "}";

  start_processing();
  httpRequest("post", url, true, handleSaveResponse, post_info);
}


function load_form()
{
  // get the form name to load
  var data = "form_id=" + $("form_list").value;
  var url = "global/ajax_load.php";
  
  start_processing();
  httpRequest("post", url, true, handleLoadResponse, data);
}


function handleSaveResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      var rawResponse  = g_request.responseText;
      var jsonResponse = eval("(" + rawResponse + ")");

      // if this form isn't listed in the form dropdown list, add it
      var already_listed = false;
      form_list_dd = $("form_list"); 
      for (f=0; f<form_list_dd.length; f++)
      {
        if (form_list_dd[f].text == jsonResponse.form_name)
          already_listed = true;
      }
      if (!already_listed)
        form_list_dd[form_list_dd.length] = new Option(jsonResponse.form_name, jsonResponse.form_id, false, false);

      var buttons = new Array();
      buttons.push('<input type="button" name="" value="OK" onclick="hide_message()" />');
      display_message("error", "Your form has been saved.", buttons);

      end_processing();
    }
  }
}


function handleLoadResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      var rawResponse  = g_request.responseText;
      var jsonResponse = eval("(" + rawResponse + ")");

			// store this last JSON response in a global. It'll be emptied once the form's been loaded.  
			g_lastJsonResponse = jsonResponse;

      if (jsonResponse.success)
      {
        // load the form name as well, to simplify saving
        var form_list = $("form_list");
        for (var i=0; i<form_list.length; i++)
        {
          if (form_list[i].selected) 
            $("save_form_name").value = form_list[i].text;
        }

        // remove all the existing rows (except the heading row)
				empty_form(false); 

        // set the other fields 
        document.data.numResults.value = jsonResponse.num_results;
        
        for (i=0; i<document.data.resultType.length; i++)
        {
          if (document.data.resultType[i].value == jsonResponse.result_type)
          {
            document.data.resultType[i].checked = true;
            changeResultType(jsonResponse.result_type);
            break;
          }
        }
        countries_arr = jsonResponse.countries.split(",");
        for (i=0; i<document.data["countryChoice[]"].length; i++)
        {
          if (countries_arr.contains(document.data["countryChoice[]"][i].value))
            document.data["countryChoice[]"][i].checked = true;
          else
            document.data["countryChoice[]"][i].checked = false;
        }
        updateCountryChoice();

        document.data.xml_root_node_name.value = decodeURIComponent(jsonResponse.xml_root_node_name);
        document.data.xml_record_node_name.value = decodeURIComponent(jsonResponse.xml_record_node_name);
        document.data.sql_table_name.value = decodeURIComponent(jsonResponse.sql_table_name);
        document.data.sql_database.value = decodeURIComponent(jsonResponse.sql_database);
        document.data.csv_delimiter.value = decodeURIComponent(jsonResponse.csv_delimiter);
        document.data.sql_create_table.checked = (jsonResponse.sql_create_table == "true") ? true : false;
        document.data.enclose_with_backquotes.checked = (jsonResponse.enclose_with_backquotes == "true") ? true : false;

        if (document.data.sql_database.value == "Oracle")
        	document.data.enclose_with_backquotes.disabled = true;

				
        // add the new blank rows
				total_rows = jsonResponse.num_rows;
        addRows(total_rows.toString());

				// populate the basics for each row (title and type)
				for (currRow=1; currRow<=total_rows; currRow++)
				{
				  $("title_" + currRow).value = decodeURIComponent(jsonResponse["title" + currRow]);

					row_type = decodeURIComponent(jsonResponse["type" + currRow]);
				  $("type_" + currRow).value = row_type;

					// we explicitly call changeRow for each row. Rows that require HTML parsing are executed
          // in timeouts to prevent timing bugs
					changeRowType("type_" + currRow, row_type);
				}
				
				// we're not done. Lastly we need to add the specific options and examples for each row.
				// Due to timing issues, we stick this task in a queue, which only gets executed once 
				// the rows are all prepped
        g_queue.push( [
				  load_row_content,
					function() { return true; }
					  ] );
      }
      else
      {
        display_message("error", jsonResponse.message);
      }

    }
  }
}

function load_row_content()
{

  // populate each of the rows content. We can do this without timeouts since we're simply settings values, 
	// not changing any HTML content 
  for (currRow=1; currRow<=g_lastJsonResponse.num_rows; currRow++)
  {
    row_type = decodeURIComponent(g_lastJsonResponse["type" + currRow]);
  
    switch (row_type)
    {
      case "Name":
      case "Phone":
      case "Alphanumeric":
        $("datatype_" + currRow).value = decodeURIComponent(g_lastJsonResponse["example" + currRow]);
        $("option_" + currRow).value   = decodeURIComponent(g_lastJsonResponse["option" + currRow]);
        break;

      case "Postal-Zip":
				var zips = decodeURIComponent(g_lastJsonResponse["option" + currRow]).split(",");
        $("includeZipCanada_" + currRow).checked = (zips.contains("canada")) ? true : false;
        $("includeZipNetherlands_" + currRow).checked = (zips.contains("netherlands")) ? true : false;
        $("includeZipUK_" + currRow).checked = (zips.contains("uk")) ? true : false;
        $("includeZipUS_" + currRow).checked = (zips.contains("us")) ? true : false;
        break;

      case "State-Province":
        var state_prov = decodeURIComponent(g_lastJsonResponse["option" + currRow]).split(",");
        $("includeRegionCanada_" + currRow).checked = (state_prov.contains("canada")) ? true : false; 
        $("includeRegionCanadaFull_" + currRow).checked = (state_prov.contains("canada_full")) ? true : false; 
        $("includeRegionCanadaShort_" + currRow).checked = (state_prov.contains("canada_short")) ? true : false;
				hideShowStateProvCounty(currRow, $("includeRegionCanada_" + currRow).checked, "Canada");
 
        $("includeRegionNetherlands_" + currRow).checked = (state_prov.contains("netherlands")) ? true : false; 
        $("includeRegionNetherlandsFull_" + currRow).checked = (state_prov.contains("netherlands_full")) ? true : false; 
        $("includeRegionNetherlandsShort_" + currRow).checked = (state_prov.contains("netherlands_short")) ? true : false; 
				hideShowStateProvCounty(currRow, $("includeRegionNetherlands_" + currRow).checked, "Netherlands");

        $("includeRegionUK_" + currRow).checked = (state_prov.contains("uk")) ? true : false; 
        $("includeRegionUKFull_" + currRow).checked = (state_prov.contains("uk_full")) ? true : false;
        $("includeRegionUKShort_" + currRow).checked = (state_prov.contains("uk_short")) ? true : false;
        hideShowStateProvCounty(currRow, $("includeRegionUK_" + currRow).checked, "UK");

        $("includeRegionUS_" + currRow).checked = (state_prov.contains("us")) ? true : false;
        $("includeRegionUSFull_" + currRow).checked = (state_prov.contains("us_full")) ? true : false; 
        $("includeRegionUSShort_" + currRow).checked = (state_prov.contains("us_short")) ? true : false;
				hideShowStateProvCounty(currRow, $("includeRegionUS_" + currRow).checked, "US");
        break;

      case "Date":
        var date_info = decodeURIComponent(g_lastJsonResponse["option" + currRow]).split(",");
        $("fromDate_" + currRow).value = date_info[0];
        $("toDate_" + currRow).value   = date_info[1];
        $("option_" + currRow).value   = date_info[2];
        break;
      
      case "Text-Fixed":
        $("numWords_" + currRow).value = decodeURIComponent(g_lastJsonResponse["option" + currRow]);
        break;

      case "Text-Random":
				var rand_text_info = decodeURIComponent(g_lastJsonResponse["option" + currRow]).split(",");
        $("startsWithLipsum_" + currRow).checked = (rand_text_info[0] == "true") ? true : false;
//        $("numWordsMin_" + currRow).value = (rand_text_info[1] == "true") ? true : false;
//        $("numWordsMax_" + currRow).value = (rand_text_info[2] == "true") ? true : false;
        $("numWordsMin_" + currRow).value = rand_text_info[1];
        $("numWordsMax_" + currRow).value = rand_text_info[2];
        break;

      case "Auto-Increment":
        $("datatype_" + currRow).value = decodeURIComponent(g_lastJsonResponse["example" + currRow]);
        var auto_increment_info = decodeURIComponent(g_lastJsonResponse["option" + currRow]).split(",");
        $("autoIncrementStart_" + currRow).value = auto_increment_info[0];
        $("autoIncrementValue_" + currRow).value = auto_increment_info[1];
        break;
      
      case "Number-Range":
				var num_range = decodeURIComponent(g_lastJsonResponse["option" + currRow]).split(",");
        $("numRangeMin_" + currRow).value = num_range[0];
        $("numRangeMax_" + currRow).value = num_range[1];
        break;
      
      case "List":
        $("datatype_" + currRow).value = decodeURIComponent(g_lastJsonResponse["example" + currRow]);
        var list = decodeURIComponent(g_lastJsonResponse["option" + currRow]).split(",");
        $("listType1_" + currRow).checked = (list[0] == "true") ? true : false;
        $("listType2_" + currRow).checked = (list[1] == "true") ? true : false;
        $("exactly_" + currRow).value = list[2];
        $("atMost_" + currRow).value = list[3];
        $("option_" + currRow).value = list[4];
        break;

      default:
        break;
		}
  }

  end_processing();
	g_lastJsonResponse = "";
}


function save_form_field_onfocus(field)
{
  if (field.value == g_default_save_form_empty_str)
    field.value = "";
  
  field.style.color = "#000000";
}

function save_form_field_onblur(field)
{
  if (field.value == "")
  {
    field.value = g_default_save_form_empty_str;
    field.style.color = "#cccccc";
  }
}


function delete_form()
{
  var buttons = new Array();

  // get the form ID to be deleted
  form_id = $("form_list").value;

	if (!form_id)
	{
    buttons.push('<input type="button" name="" value="OK" onclick="hide_message()" />');
    display_message("error", "Please select a form to delete.", buttons);
		return false;	
	}

	buttons.push('<input type="button" name="" value="Yes" onclick="delete_form_confirm()" />'); 
	buttons.push('<input type="button" name="" value="No" onclick="hide_message()" />');
	
	// check it's okay with the user first
  display_message("error", "Are you sure you want to delete this form?", buttons);
}


function delete_form_confirm()
{
  var url = "global/ajax_delete_form.php";
  var form_id = $("form_list").value;
  var data = "form_id=" + form_id;

  start_processing();
  httpRequest("post", url, true, handleDeleteResponse, data);
}


function handleDeleteResponse()
{
  if (g_request.readyState == 4)
  {
    if (g_request.status == 200)
    {
      var rawResponse  = g_request.responseText;
      var jsonResponse = eval("(" + rawResponse + ")");

      if (jsonResponse.success)
      {
			  // it was deleted. Remove it from the dropdown list and inform the user
        form_list = $("form_list");
				for (i=0; i<form_list.options.length; i++)
				{
				  if (form_list.options[i].value == jsonResponse.form_id)
					  form_list.options[i] = null;
				}

			  var buttons = new Array();
        buttons.push('<input type="button" name="" value="OK" onclick="hide_message()" />');
        display_message("error", "The form has been deleted.", buttons);			 
				
        end_processing();				 
			}
			else
			{
			  var buttons = new Array();
        buttons.push('<input type="button" name="" value="OK" onclick="hide_message()" />');
        display_message("error", "Sorry, we couldn't delete this form. Re-log in and try again.", buttons);
				
        end_processing();
			}
	  }
	}
}


// message type: "notify" / "error"
// message: string to display
// buttons: array of buttons
function display_message(message_type, message, buttons)
{
  var className = (message_type == "error") ? "error" : "notify";

	var buttons_str;
	if (buttons)
	{
  	buttons_str = "<div style='float:right;'>";
		for (i=0; i<buttons.length; i++)
		  buttons_str += buttons[i];
		buttons_str += "</div>";
	}
  $("control_panel").style.display = "none";
  $("control_panel_message").style.display = "block";
  $("control_panel_box").className = className;
	$("control_panel_message").innerHTML = "<img src='images/alert.jpg' align='left' />" + buttons_str + message;
}

function hide_message()
{
  Effect.Fade('control_panel_message'); // takes 1 second
  setTimeout('$("control_panel_box").className = "box";', 1000);
  setTimeout('$("control_panel").style.display = "block";', 1000);
}


// -----------------------------------------------------------------------------------------------


Array.prototype.contains = function(value)
{
  var found = false;

  for (j=0; j<this.length; j++)
  {
    if (this[j] == value)
      found = true;
  }
  return found;
}


// --------------------------------------------------------------------------
// postit.js v1.0
// written by: Benjamin Keen, August 2003
// --------------------------------------------------------------------------
// For an explanation of the script, see attached example.html, or visit 
// benjaminkeen.org


/* ------------------------------------------------------------------------*/
// CONFIGURATION SETTINGS

// Default styles
var postitStyles = new Object();

postitStyles = {
  'width':                  '200',
  'height':                 'auto',   
  'backgroundColor':        '#FFFFCC',
  'fontFamily':             'verdana', 
  'fontSize':               '8pt', 
	
  'padding':                '8px',
  'border':                 '1px solid #999999',
  'position':               'absolute',
  'z-index':                '100'
}

var _x_offset = 10;      // # of pixels x is offset from location of mouse click   
var _y_offset = 10;      // # of pixels y is offset from location of mouse click

/* ------------------------------------------------------------------------*/



// --------------------------------------------------------------------------
// function:    initializePostits() 
// description: called by body onload handler. This automatically hides all 
//              post-its on the page. Post-its are identified by having an 
//              id with this format: id="postitX" - where X is any integer. 
// --------------------------------------------------------------------------
function initializePostits() {

  // find all post-its 
	var postits = document.getElementsByTagName('div');
	var postitElementsArray = new Array();         // stores id's of all post-its

	for (i=0; i<postits.length; i++) {
    if (postits[i].id.match(/^postit/i)) { 
		  postitElementsArray.push(postits[i].id);
		}
	}
		
	// hide all post-its
  for (i=0; i<postitElementsArray.length; i++) {
	  $(postitElementsArray[i]).style.display = "none";
	}

	
	// set default post-it styles. Individual post-it styles may be overridden 
	// later by showPostit()
	for (styleName in postitStyles) {

		// set style for each unique postit
    for (i=0; i<postitElementsArray.length; i++) {
			$(postitElementsArray[i]).style[styleName] = postitStyles[styleName]; 
	  }

	}
}


// --------------------------------------------------------------------------
// function:    currentMousePosition()
// description: helper function to store location of mouse in global var
//              so we can access those values in Netscape 
// --------------------------------------------------------------------------
window.onmousemove = currentMousePosition;
var _x;       // global var to keep track of x mouse co-ordinate
var _y;       // global var to keep track of y mouse co-ordinate

function currentMousePosition(e) {  
  if (document.layers || $&&!document.all) { 
	  _x = e.pageX;
		_y = e.pageY;
  }
} 


// --------------------------------------------------------------------------
// function:    showPostit()
// parameters:  - postitId: the unique id of the post-it (required)
//              - quadrant: 1=top-left, 2=top-right, 3=bottom-left, 4=bottom-right
//                          if 'null' uses default (optional)
//              - w:        width of post-it. if 'null' uses default (optional)
//              - h:        height of post-it. if 'null' uses default (optional)
//              - bc:       background color. if 'null' uses default (optional)
// --------------------------------------------------------------------------
function showPostit(postitId, quadrant, w, h, bc) {

	// Find x & y mouse location to figure out where to display the post-it
  var isIE = document.all ? true : false;	
	var x_coord = isIE ? event.clientX + document.body.scrollLeft : _x;
	var y_coord = isIE ? event.clientY + document.body.scrollTop  : _y;

  y_coord -= findPosY($("content"));
  x_coord -= findPosX($("content"));

	var postitStyle = $(postitId).style;
	
  
	// custom post-it size
	if (w) { postitStyle.width = w;	}
	if (h) { postitStyle.height = h;	}
	
	
  // toggle post-it visibility 
  if (postitStyle.display && postitStyle.display != 'none') { 
	  postitStyle.display = 'none';	
	}
	else { postitStyle.display = 'block'; }


	// calculate location of post-it. We do this *after* making it visible, since 
	// we can't ascertain the height of an element with 'auto' size unless it is 
	// visible. 
	var new_x_coord = x_coord + _x_offset;
	var new_y_coord = y_coord + _y_offset;

	var psw = Number(postitStyle.width.replace(/\D/g, ""));
	var psh = Number(postitStyle.height.replace(/\D/g, ""));
	
  if (psh == 0) { psh = $(postitId).offsetHeight; }

  switch (quadrant) {
	  case 1:                            // top-left
		  new_x_coord = x_coord - (psw + _x_offset);
		  new_y_coord = y_coord - (psh + _y_offset);
		  break;
		case 2:                            // top-right
		  new_x_coord = x_coord + _x_offset;
		  new_y_coord = y_coord - (psh + _y_offset);
		  break;		
		case 3:                            // bottom-left
		  new_x_coord = x_coord - (psw + _x_offset);
		  new_y_coord = y_coord + _y_offset;
		  break;		
		case 4:                            // bottom-right
		  new_x_coord = x_coord + _x_offset;
		  new_y_coord = y_coord + _y_offset;		
		  break;
	} 
	
  postitStyle.top  = new_y_coord;
  postitStyle.left = new_x_coord;

	// set the color
	if (bc) { postitStyle.backgroundColor = bc; }
	
	return false;
}


function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (1) 
		{
			curleft += obj.offsetLeft;
			if (!obj.offsetParent)
				break;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function findPosY(obj)
{
  var curtop = 0;
  if (obj.offsetParent)
  {
	  while (1)
    {
      curtop += obj.offsetTop;
      if (!obj.offsetParent)
        break;
      obj = obj.offsetParent;
    }
	}

  else if (obj.y)
    curtop += obj.y;

  return curtop;
}

// ===================================================================
// Author: Matt Kruse <matt@mattkruse.com>
// WWW: http://www.mattkruse.com/
// ===================================================================

// getAnchorPosition(anchorname)
//   This function returns an object having .x and .y properties which are the coordinates
//   of the named anchor, relative to the page.
function getAnchorPosition(anchorname) {
	// This function will return an Object with x and y properties
	var useWindow=false;
	var coordinates=new Object();
	var x=0,y=0;
	// Browser capability sniffing
	var use_gebi=false, use_css=false, use_layers=false;
	if (document.getElementById) { use_gebi=true; }
	else if (document.all) { use_css=true; }
	else if (document.layers) { use_layers=true; }
	// Logic to find position
 	if (use_gebi && document.all) {
		x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
		y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
		}
	else if (use_gebi) {
		var o=$(anchorname);
		x=AnchorPosition_getPageOffsetLeft(o);
		y=AnchorPosition_getPageOffsetTop(o);
		}
 	else if (use_css) {
		x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
		y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
		}
	else if (use_layers) {
		var found=0;
		for (var i=0; i<document.anchors.length; i++) {
			if (document.anchors[i].name==anchorname) { found=1; break; }
			}
		if (found==0) {
			coordinates.x=0; coordinates.y=0; return coordinates;
			}
		x=document.anchors[i].x;
		y=document.anchors[i].y;
		}
	else {
		coordinates.x=0; coordinates.y=0; return coordinates;
		}
	coordinates.x=x;
	coordinates.y=y;
	return coordinates;
	}

// getAnchorWindowPosition(anchorname)
//   This function returns an object having .x and .y properties which are the coordinates
//   of the named anchor, relative to the window
function getAnchorWindowPosition(anchorname) {
	var coordinates=getAnchorPosition(anchorname);
	var x=0;
	var y=0;
	if (document.getElementById) {
		if (isNaN(window.screenX)) {
			x=coordinates.x-document.body.scrollLeft+window.screenLeft;
			y=coordinates.y-document.body.scrollTop+window.screenTop;
			}
		else {
			x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
			y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
			}
		}
	else if (document.all) {
		x=coordinates.x-document.body.scrollLeft+window.screenLeft;
		y=coordinates.y-document.body.scrollTop+window.screenTop;
		}
	else if (document.layers) {
		x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
		y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
		}
	coordinates.x=x;
	coordinates.y=y;
	return coordinates;
	}

// Functions for IE to get position of an object
function AnchorPosition_getPageOffsetLeft (el) {
	var ol=el.offsetLeft;
	while ((el=el.offsetParent) != null) { ol += el.offsetLeft; }
	return ol;
	}
function AnchorPosition_getWindowOffsetLeft (el) {
	return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;
	}	
function AnchorPosition_getPageOffsetTop (el) {
	var ot=el.offsetTop;
	while((el=el.offsetParent) != null) { ot += el.offsetTop; }
	return ot;
	}
function AnchorPosition_getWindowOffsetTop (el) {
	return AnchorPosition_getPageOffsetTop(el)-document.body.scrollTop;
	}

/* SOURCE FILE: date.js */

var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
function LZ(x) {return(x<0||x>9?"":"0")+x}

// ------------------------------------------------------------------
// isDate ( date_string, format_string )
// Returns true if date string matches format of format string and
// is a valid date. Else returns false.
// It is recommended that you trim whitespace around the value before
// passing it to this function, as whitespace is NOT ignored!
// ------------------------------------------------------------------
function isDate(val,format) {
	var date=getDateFromFormat(val,format);
	if (date==0) { return false; }
	return true;
	}

// -------------------------------------------------------------------
// compareDates(date1,date1format,date2,date2format)
//   Compare two date strings to see which is greater.
//   Returns:
//   1 if date1 is greater than date2
//   0 if date2 is greater than date1 of if they are the same
//  -1 if either of the dates is in an invalid format
// -------------------------------------------------------------------
function compareDates(date1,dateformat1,date2,dateformat2) {
	var d1=getDateFromFormat(date1,dateformat1);
	var d2=getDateFromFormat(date2,dateformat2);
	if (d1==0 || d2==0) {
		return -1;
		}
	else if (d1 > d2) {
		return 1;
		}
	return 0;
	}

// ------------------------------------------------------------------
// formatDate (date_object, format)
// Returns a date in the output format specified.
// The format string uses the same abbreviations as in getDateFromFormat()
// ------------------------------------------------------------------
function formatDate(date,format) {
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var E=date.getDay();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=LZ(M);
	value["MMM"]=MONTH_NAMES[M-1];
	value["NNN"]=MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=LZ(d);
	value["E"]=DAY_NAMES[E+7];
	value["EE"]=DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=LZ(value["K"]);
	value["kk"]=LZ(value["k"]);
	if (H > 11) { value["a"]="PM"; }
	else { value["a"]="AM"; }
	value["m"]=m;
	value["mm"]=LZ(m);
	value["s"]=s;
	value["ss"]=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	}
	
// ------------------------------------------------------------------
// Utility functions for parsing in getDateFromFormat()
// ------------------------------------------------------------------
function _isInteger(val) {
	var digits="1234567890";
	for (var i=0; i < val.length; i++) {
		if (digits.indexOf(val.charAt(i))==-1) { return false; }
		}
	return true;
	}
function _getInt(str,i,minlength,maxlength) {
	for (var x=maxlength; x>=minlength; x--) {
		var token=str.substring(i,i+x);
		if (token.length < minlength) { return null; }
		if (_isInteger(token)) { return token; }
		}
	return null;
	}
	
// ------------------------------------------------------------------
// getDateFromFormat( date_string , format_string )
//
// This function takes a date string and a format string. It matches
// If the date string matches the format string, it returns the 
// getTime() of the date. If it does not match, it returns 0.
// ------------------------------------------------------------------
function getDateFromFormat(val,format) {
	val=val+"";
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getYear();
	var month=now.getMonth()+1;
	var date=1;
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";
	
	while (i_format < format.length) {
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }
			if (token=="yy")   { x=2;y=2; }
			if (token=="y")    { x=2;y=4; }
			year=_getInt(val,i_val,x,y);
			if (year==null) { return 0; }
			i_val += year.length;
			if (year.length==2) {
				if (year > 70) { year=1900+(year-0); }
				else { year=2000+(year-0); }
				}
			}
		else if (token=="MMM"||token=="NNN"){
			month=0;
			for (var i=0; i<MONTH_NAMES.length; i++) {
				var month_name=MONTH_NAMES[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					if (token=="MMM"||(token=="NNN"&&i>11)) {
						month=i+1;
						if (month>12) { month -= 12; }
						i_val += month_name.length;
						break;
						}
					}
				}
			if ((month < 1)||(month>12)){return 0;}
			}
		else if (token=="EE"||token=="E"){
			for (var i=0; i<DAY_NAMES.length; i++) {
				var day_name=DAY_NAMES[i];
				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
					i_val += day_name.length;
					break;
					}
				}
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,token.length,2);
			if(month==null||(month<1)||(month>12)){return 0;}
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,token.length,2);
			if(date==null||(date<1)||(date>31)){return 0;}
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>12)){return 0;}
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>23)){return 0;}
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>11)){return 0;}
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>24)){return 0;}
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,token.length,2);
			if(mm==null||(mm<0)||(mm>59)){return 0;}
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss==null||(ss<0)||(ss>59)){return 0;}
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
			else {return 0;}
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
			else {i_val+=token.length;}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) { return 0; }
	// Is date valid for month?
	if (month==2) {
		// Check for leap year
		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
			if (date > 29){ return 0; }
			}
		else { if (date > 28) { return 0; } }
		}
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return 0; }
		}
	// Correct hours value
	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
	else if (hh>11 && ampm=="AM") { hh-=12; }
	var newdate=new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
	}

// ------------------------------------------------------------------
// parseDate( date_string [, prefer_euro_format] )
//
// This function takes a date string and tries to match it to a
// number of possible date formats to get the value. It will try to
// match against the following international formats, in this order:
// y-M-d   MMM d, y   MMM d,y   y-MMM-d   d-MMM-y  MMM d
// M/d/y   M-d-y      M.d.y     MMM-d     M/d      M-d
// d/M/y   d-M-y      d.M.y     d-MMM     d/M      d-M
// A second argument may be passed to instruct the method to search
// for formats like d/M/y (european format) before M/d/y (American).
// Returns a Date object or null if no patterns match.
// ------------------------------------------------------------------
function parseDate(val) {
	var preferEuro=(arguments.length==2)?arguments[1]:false;
	generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
	monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
	dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
	var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
	var d=null;
	for (var i=0; i<checkList.length; i++) {
		var l=window[checkList[i]];
		for (var j=0; j<l.length; j++) {
			d=getDateFromFormat(val,l[j]);
			if (d!=0) { return new Date(d); }
			}
		}
	return null;
	}

// Set the position of the popup window based on the anchor
function PopupWindow_getXYPosition(anchorname) {
	var coordinates;
	if (this.type == "WINDOW") {
		coordinates = getAnchorWindowPosition(anchorname);
		}
	else {
		coordinates = getAnchorPosition(anchorname);
		}
	this.x = coordinates.x;
	this.y = coordinates.y;
	}
// Set width/height of DIV/popup window
function PopupWindow_setSize(width,height) {
	this.width = width;
	this.height = height;
	}
// Fill the window with contents
function PopupWindow_populate(contents) {
	this.contents = contents;
	this.populated = false;
	}
// Set the URL to go to
function PopupWindow_setUrl(url) {
	this.url = url;
	}
// Set the window popup properties
function PopupWindow_setWindowProperties(props) {
	this.windowProperties = props;
	}
// Refresh the displayed contents of the popup
function PopupWindow_refresh() {
	if (this.divName != null) {
		// refresh the DIV object
		if (this.use_gebi) {
			$(this.divName).innerHTML = this.contents;
			}
		else if (this.use_css) { 
			document.all[this.divName].innerHTML = this.contents;
			}
		else if (this.use_layers) { 
			var d = document.layers[this.divName]; 
			d.document.open();
			d.document.writeln(this.contents);
			d.document.close();
			}
		}
	else {
		if (this.popupWindow != null && !this.popupWindow.closed) {
			if (this.url!="") {
				this.popupWindow.location.href=this.url;
				}
			else {
				this.popupWindow.document.open();
				this.popupWindow.document.writeln(this.contents);
				this.popupWindow.document.close();
			}
			this.popupWindow.focus();
			}
		}
	}
// Position and show the popup, relative to an anchor object
function PopupWindow_showPopup(anchorname) {
	this.getXYPosition(anchorname);
	this.x += this.offsetX;
	this.y += this.offsetY;
	if (!this.populated && (this.contents != "")) {
		this.populated = true;
		this.refresh();
		}
	if (this.divName != null) {
		// Show the DIV object
		if (this.use_gebi) {
			$(this.divName).style.left = this.x + "px";
			$(this.divName).style.top = this.y + "px";
			$(this.divName).style.visibility = "visible";
			}
		else if (this.use_css) {
			document.all[this.divName].style.left = this.x;
			document.all[this.divName].style.top = this.y;
			document.all[this.divName].style.visibility = "visible";
			}
		else if (this.use_layers) {
			document.layers[this.divName].left = this.x;
			document.layers[this.divName].top = this.y;
			document.layers[this.divName].visibility = "visible";
			}
		}
	else {
		if (this.popupWindow == null || this.popupWindow.closed) {
			// If the popup window will go off-screen, move it so it doesn't
			if (this.x<0) { this.x=0; }
			if (this.y<0) { this.y=0; }
			if (screen && screen.availHeight) {
				if ((this.y + this.height) > screen.availHeight) {
					this.y = screen.availHeight - this.height;
					}
				}
			if (screen && screen.availWidth) {
				if ((this.x + this.width) > screen.availWidth) {
					this.x = screen.availWidth - this.width;
					}
				}
			var avoidAboutBlank = window.opera || ( document.layers && !navigator.mimeTypes['*'] ) || navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled );
			this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");
			}
		this.refresh();
		}
	}
// Hide the popup
function PopupWindow_hidePopup() {
	if (this.divName != null) {
		if (this.use_gebi) {
			$(this.divName).style.visibility = "hidden";
			}
		else if (this.use_css) {
			document.all[this.divName].style.visibility = "hidden";
			}
		else if (this.use_layers) {
			document.layers[this.divName].visibility = "hidden";
			}
		}
	else {
		if (this.popupWindow && !this.popupWindow.closed) {
			this.popupWindow.close();
			this.popupWindow = null;
			}
		}
	}
// Pass an event and return whether or not it was the popup DIV that was clicked
function PopupWindow_isClicked(e) {
	if (this.divName != null) {
		if (this.use_layers) {
			var clickX = e.pageX;
			var clickY = e.pageY;
			var t = document.layers[this.divName];
			if ((clickX > t.left) && (clickX < t.left+t.clip.width) && (clickY > t.top) && (clickY < t.top+t.clip.height)) {
				return true;
				}
			else { return false; }
			}
		else if (document.all) { // Need to hard-code this to trap IE for error-handling
			var t = window.event.srcElement;
			while (t.parentElement != null) {
				if (t.id==this.divName) {
					return true;
					}
				t = t.parentElement;
				}
			return false;
			}
		else if (this.use_gebi && e) {
			var t = e.originalTarget;
			while (t.parentNode != null) {
				if (t.id==this.divName) {
					return true;
					}
				t = t.parentNode;
				}
			return false;
			}
		return false;
		}
	return false;
	}

// Check an onMouseDown event to see if we should hide
function PopupWindow_hideIfNotClicked(e) {
	if (this.autoHideEnabled && !this.isClicked(e)) {
		this.hidePopup();
		}
	}
// Call this to make the DIV disable automatically when mouse is clicked outside it
function PopupWindow_autoHide() {
	this.autoHideEnabled = true;
	}
// This global function checks all PopupWindow objects onmouseup to see if they should be hidden
function PopupWindow_hidePopupWindows(e) {
	for (var i=0; i<popupWindowObjects.length; i++) {
		if (popupWindowObjects[i] != null) {
			var p = popupWindowObjects[i];
			p.hideIfNotClicked(e);
			}
		}
	}
// Run this immediately to attach the event listener
function PopupWindow_attachListener() {
	if (document.layers) {
		document.captureEvents(Event.MOUSEUP);
		}
	window.popupWindowOldEventListener = document.onmouseup;
	if (window.popupWindowOldEventListener != null) {
		document.onmouseup = new Function("window.popupWindowOldEventListener(); PopupWindow_hidePopupWindows();");
		}
	else {
		document.onmouseup = PopupWindow_hidePopupWindows;
		}
	}
// CONSTRUCTOR for the PopupWindow object
// Pass it a DIV name to use a DHTML popup, otherwise will default to window popup
function PopupWindow() {
	if (!window.popupWindowIndex) { window.popupWindowIndex = 0; }
	if (!window.popupWindowObjects) { window.popupWindowObjects = new Array(); }
	if (!window.listenerAttached) {
		window.listenerAttached = true;
		PopupWindow_attachListener();
		}
	this.index = popupWindowIndex++;
	popupWindowObjects[this.index] = this;
	this.divName = null;
	this.popupWindow = null;
	this.width=0;
	this.height=0;
	this.populated = false;
	this.visible = false;
	this.autoHideEnabled = false;
	
	this.contents = "";
	this.url="";
	this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";
	if (arguments.length>0) {
		this.type="DIV";
		this.divName = arguments[0];
		}
	else {
		this.type="WINDOW";
		}
	this.use_gebi = false;
	this.use_css = false;
	this.use_layers = false;
	if (document.getElementById) { this.use_gebi = true; }
	else if (document.all) { this.use_css = true; }
	else if (document.layers) { this.use_layers = true; }
	else { this.type = "WINDOW"; }
	this.offsetX = 0;
	this.offsetY = 0;
	// Method mappings
	this.getXYPosition = PopupWindow_getXYPosition;
	this.populate = PopupWindow_populate;
	this.setUrl = PopupWindow_setUrl;
	this.setWindowProperties = PopupWindow_setWindowProperties;
	this.refresh = PopupWindow_refresh;
	this.showPopup = PopupWindow_showPopup;
	this.hidePopup = PopupWindow_hidePopup;
	this.setSize = PopupWindow_setSize;
	this.isClicked = PopupWindow_isClicked;
	this.autoHide = PopupWindow_autoHide;
	this.hideIfNotClicked = PopupWindow_hideIfNotClicked;
	}

// CONSTRUCTOR for the CalendarPopup Object
function CalendarPopup() {
	var c;
	if (arguments.length>0) {
		c = new PopupWindow(arguments[0]);
		}
	else {
		c = new PopupWindow();
		c.setSize(150,175);
		}
	c.offsetX = -152;
	c.offsetY = 25;
	c.autoHide();
	// Calendar-specific properties
	c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
	c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
	c.dayHeaders = new Array("S","M","T","W","T","F","S");
	c.returnFunction = "CP_tmpReturnFunction";
	c.returnMonthFunction = "CP_tmpReturnMonthFunction";
	c.returnQuarterFunction = "CP_tmpReturnQuarterFunction";
	c.returnYearFunction = "CP_tmpReturnYearFunction";
	c.weekStartDay = 0;
	c.isShowYearNavigation = false;
	c.displayType = "date";
	c.disabledWeekDays = new Object();
	c.disabledDatesExpression = "";
	c.yearSelectStartOffset = 2;
	c.currentDate = null;
	c.todayText="Today";
	c.cssPrefix="";
	c.isShowNavigationDropdowns=false;
	c.isShowYearNavigationInput=false;
	window.CP_calendarObject = null;
	window.CP_targetInput = null;
	window.CP_dateFormat = "MM/dd/yyyy";
	// Method mappings
	c.copyMonthNamesToWindow = CP_copyMonthNamesToWindow;
	c.setReturnFunction = CP_setReturnFunction;
	c.setReturnMonthFunction = CP_setReturnMonthFunction;
	c.setReturnQuarterFunction = CP_setReturnQuarterFunction;
	c.setReturnYearFunction = CP_setReturnYearFunction;
	c.setMonthNames = CP_setMonthNames;
	c.setMonthAbbreviations = CP_setMonthAbbreviations;
	c.setDayHeaders = CP_setDayHeaders;
	c.setWeekStartDay = CP_setWeekStartDay;
	c.setDisplayType = CP_setDisplayType;
	c.setDisabledWeekDays = CP_setDisabledWeekDays;
	c.addDisabledDates = CP_addDisabledDates;
	c.setYearSelectStartOffset = CP_setYearSelectStartOffset;
	c.setTodayText = CP_setTodayText;
	c.showYearNavigation = CP_showYearNavigation;
	c.showCalendar = CP_showCalendar;
	c.hideCalendar = CP_hideCalendar;
	c.getStyles = getCalendarStyles;
	c.refreshCalendar = CP_refreshCalendar;
	c.getCalendar = CP_getCalendar;
	c.select = CP_select;
	c.setCssPrefix = CP_setCssPrefix;
	c.showNavigationDropdowns = CP_showNavigationDropdowns;
	c.showYearNavigationInput = CP_showYearNavigationInput;
	c.copyMonthNamesToWindow();
	// Return the object
	return c;
	}
function CP_copyMonthNamesToWindow() {
	// Copy these values over to the date.js 
	if (typeof(window.MONTH_NAMES)!="undefined" && window.MONTH_NAMES!=null) {
		window.MONTH_NAMES = new Array();
		for (var i=0; i<this.monthNames.length; i++) {
			window.MONTH_NAMES[window.MONTH_NAMES.length] = this.monthNames[i];
		}
		for (var i=0; i<this.monthAbbreviations.length; i++) {
			window.MONTH_NAMES[window.MONTH_NAMES.length] = this.monthAbbreviations[i];
		}
	}
}
// Temporary default functions to be called when items clicked, so no error is thrown
function CP_tmpReturnFunction(y,m,d) { 
	if (window.CP_targetInput!=null) {
		var dt = new Date(y,m-1,d,0,0,0);
		if (window.CP_calendarObject!=null) { window.CP_calendarObject.copyMonthNamesToWindow(); }
		window.CP_targetInput.value = formatDate(dt,window.CP_dateFormat);
		}
	else {
		alert('Use setReturnFunction() to define which function will get the clicked results!'); 
		}
	}
function CP_tmpReturnMonthFunction(y,m) { 
	alert('Use setReturnMonthFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , month='+m); 
	}
function CP_tmpReturnQuarterFunction(y,q) { 
	alert('Use setReturnQuarterFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , quarter='+q); 
	}
function CP_tmpReturnYearFunction(y) { 
	alert('Use setReturnYearFunction() to define which function will get the clicked results!\nYou clicked: year='+y); 
	}

// Set the name of the functions to call to get the clicked item
function CP_setReturnFunction(name) { this.returnFunction = name; }
function CP_setReturnMonthFunction(name) { this.returnMonthFunction = name; }
function CP_setReturnQuarterFunction(name) { this.returnQuarterFunction = name; }
function CP_setReturnYearFunction(name) { this.returnYearFunction = name; }

// Over-ride the built-in month names
function CP_setMonthNames() {
	for (var i=0; i<arguments.length; i++) { this.monthNames[i] = arguments[i]; }
	this.copyMonthNamesToWindow();
	}

// Over-ride the built-in month abbreviations
function CP_setMonthAbbreviations() {
	for (var i=0; i<arguments.length; i++) { this.monthAbbreviations[i] = arguments[i]; }
	this.copyMonthNamesToWindow();
	}

// Over-ride the built-in column headers for each day
function CP_setDayHeaders() {
	for (var i=0; i<arguments.length; i++) { this.dayHeaders[i] = arguments[i]; }
	}

// Set the day of the week (0-7) that the calendar display starts on
// This is for countries other than the US whose calendar displays start on Monday(1), for example
function CP_setWeekStartDay(day) { this.weekStartDay = day; }

// Show next/last year navigation links
function CP_showYearNavigation() { this.isShowYearNavigation = (arguments.length>0)?arguments[0]:true; }

// Which type of calendar to display
function CP_setDisplayType(type) {
	if (type!="date"&&type!="week-end"&&type!="month"&&type!="quarter"&&type!="year") { alert("Invalid display type! Must be one of: date,week-end,month,quarter,year"); return false; }
	this.displayType=type;
	}

// How many years back to start by default for year display
function CP_setYearSelectStartOffset(num) { this.yearSelectStartOffset=num; }

// Set which weekdays should not be clickable
function CP_setDisabledWeekDays() {
	this.disabledWeekDays = new Object();
	for (var i=0; i<arguments.length; i++) { this.disabledWeekDays[arguments[i]] = true; }
	}
	
// Disable individual dates or ranges
// Builds an internal logical test which is run via eval() for efficiency
function CP_addDisabledDates(start, end) {
	if (arguments.length==1) { end=start; }
	if (start==null && end==null) { return; }
	if (this.disabledDatesExpression!="") { this.disabledDatesExpression+= "||"; }
	if (start!=null) { start = parseDate(start); start=""+start.getFullYear()+LZ(start.getMonth()+1)+LZ(start.getDate());}
	if (end!=null) { end=parseDate(end); end=""+end.getFullYear()+LZ(end.getMonth()+1)+LZ(end.getDate());}
	if (start==null) { this.disabledDatesExpression+="(ds<="+end+")"; }
	else if (end  ==null) { this.disabledDatesExpression+="(ds>="+start+")"; }
	else { this.disabledDatesExpression+="(ds>="+start+"&&ds<="+end+")"; }
	}
	
// Set the text to use for the "Today" link
function CP_setTodayText(text) {
	this.todayText = text;
	}

// Set the prefix to be added to all CSS classes when writing output
function CP_setCssPrefix(val) { 
	this.cssPrefix = val; 
	}

// Show the navigation as an dropdowns that can be manually changed
function CP_showNavigationDropdowns() { this.isShowNavigationDropdowns = (arguments.length>0)?arguments[0]:true; }

// Show the year navigation as an input box that can be manually changed
function CP_showYearNavigationInput() { this.isShowYearNavigationInput = (arguments.length>0)?arguments[0]:true; }

// Hide a calendar object
function CP_hideCalendar() {
	if (arguments.length > 0) { window.popupWindowObjects[arguments[0]].hidePopup(); }
	else { this.hidePopup(); }
	}

// Refresh the contents of the calendar display
function CP_refreshCalendar(index) {
	var calObject = window.popupWindowObjects[index];
	if (arguments.length>1) { 
		calObject.populate(calObject.getCalendar(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]));
		}
	else {
		calObject.populate(calObject.getCalendar());
		}
	calObject.refresh();
	}

// Populate the calendar and display it
function CP_showCalendar(anchorname) {
	if (arguments.length>1) {
		if (arguments[1]==null||arguments[1]=="") {
			this.currentDate=new Date();
			}
		else {
			this.currentDate=new Date(parseDate(arguments[1]));
			}
		}
	this.populate(this.getCalendar());
	this.showPopup(anchorname);
	}

// Simple method to interface popup calendar with a text-entry box
function CP_select(inputobj, linkname, format) {
	var selectedDate=(arguments.length>3)?arguments[3]:null;
	if (!window.getDateFromFormat) {
		alert("calendar.select: To use this method you must also include 'date.js' for date formatting");
		return;
		}
	if (this.displayType!="date"&&this.displayType!="week-end") {
		alert("calendar.select: This function can only be used with displayType 'date' or 'week-end'");
		return;
		}
	if (inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea") { 
		alert("calendar.select: Input object passed is not a valid form input object"); 
		window.CP_targetInput=null;
		return;
		}
	if (inputobj.disabled) { return; } // Can't use calendar input on disabled form input!
	window.CP_targetInput = inputobj;
	window.CP_calendarObject = this;
	this.currentDate=null;
	var time=0;
	if (selectedDate!=null) {
		time = getDateFromFormat(selectedDate,format)
		}
	else if (inputobj.value!="") {
		time = getDateFromFormat(inputobj.value,format);
		}
	if (selectedDate!=null || inputobj.value!="") {
		if (time==0) { this.currentDate=null; }
		else { this.currentDate=new Date(time); }
		}
	window.CP_dateFormat = format;
	this.showCalendar(linkname);
	}
	
// Get style block needed to display the calendar correctly
function getCalendarStyles() {
	var result = "";
	var p = "";
	if (this!=null && typeof(this.cssPrefix)!="undefined" && this.cssPrefix!=null && this.cssPrefix!="") { p=this.cssPrefix; }
	result += "<STYLE>\n";
	result += "."+p+"cpYearNavigation,."+p+"cpMonthNavigation { background-color:#C0C0C0; text-align:center; vertical-align:center; text-decoration:none; color:#000000; font-weight:bold; }\n";
	result += "."+p+"cpDayColumnHeader, ."+p+"cpYearNavigation,."+p+"cpMonthNavigation,."+p+"cpCurrentMonthDate,."+p+"cpCurrentMonthDateDisabled,."+p+"cpOtherMonthDate,."+p+"cpOtherMonthDateDisabled,."+p+"cpCurrentDate,."+p+"cpCurrentDateDisabled,."+p+"cpTodayText,."+p+"cpTodayTextDisabled,."+p+"cpText { font-family:arial; font-size:8pt; }\n";
	result += "TD."+p+"cpDayColumnHeader { text-align:right; border:solid thin #C0C0C0;border-width:0px 0px 1px 0px; }\n";
	result += "."+p+"cpCurrentMonthDate, ."+p+"cpOtherMonthDate, ."+p+"cpCurrentDate  { text-align:right; text-decoration:none; }\n";
	result += "."+p+"cpCurrentMonthDateDisabled, ."+p+"cpOtherMonthDateDisabled, ."+p+"cpCurrentDateDisabled { color:#D0D0D0; text-align:right; text-decoration:line-through; }\n";
	result += "."+p+"cpCurrentMonthDate, .cpCurrentDate { color:#000000; }\n";
	result += "."+p+"cpOtherMonthDate { color:#808080; }\n";
	result += "TD."+p+"cpCurrentDate { color:white; background-color: #C0C0C0; border-width:1px; border:solid thin #800000; }\n";
	result += "TD."+p+"cpCurrentDateDisabled { border-width:1px; border:solid thin #FFAAAA; }\n";
	result += "TD."+p+"cpTodayText, TD."+p+"cpTodayTextDisabled { border:solid thin #C0C0C0; border-width:1px 0px 0px 0px;}\n";
	result += "A."+p+"cpTodayText, SPAN."+p+"cpTodayTextDisabled { height:20px; }\n";
	result += "A."+p+"cpTodayText { color:black; }\n";
	result += "."+p+"cpTodayTextDisabled { color:#D0D0D0; }\n";
	result += "."+p+"cpBorder { border:solid thin #808080; }\n";
	result += "</STYLE>\n";
	return result;
	}

// Return a string containing all the calendar code to be displayed
function CP_getCalendar() {
	var now = new Date();
	// Reference to window
	if (this.type == "WINDOW") { var windowref = "window.opener."; }
	else { var windowref = ""; }
	var result = "";
	// If POPUP, write entire HTML document
	if (this.type == "WINDOW") {
		result += "<HTML><HEAD><TITLE>Calendar</TITLE>"+this.getStyles()+"</HEAD><BODY MARGINWIDTH=0 MARGINHEIGHT=0 TOPMARGIN=0 RIGHTMARGIN=0 LEFTMARGIN=0>\n";
		result += '<CENTER><TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>\n';
		}
	else {
		result += '<TABLE CLASS="'+this.cssPrefix+'cpBorder" WIDTH=144 BORDER=1 BORDERWIDTH=1 CELLSPACING=0 CELLPADDING=1>\n';
		result += '<TR><TD ALIGN=CENTER>\n';
		result += '<CENTER>\n';
		}
	// Code for DATE display (default)
	// -------------------------------
	if (this.displayType=="date" || this.displayType=="week-end") {
		if (this.currentDate==null) { this.currentDate = now; }
		if (arguments.length > 0) { var month = arguments[0]; }
			else { var month = this.currentDate.getMonth()+1; }
		if (arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]) { var year = arguments[1]; }
			else { var year = this.currentDate.getFullYear(); }
		var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
		if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) {
			daysinmonth[2] = 29;
			}
		var current_month = new Date(year,month-1,1);
		var display_year = year;
		var display_month = month;
		var display_date = 1;
		var weekday= current_month.getDay();
		var offset = 0;
		
		offset = (weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ;
		if (offset > 0) {
			display_month--;
			if (display_month < 1) { display_month = 12; display_year--; }
			display_date = daysinmonth[display_month]-offset+1;
			}
		var next_month = month+1;
		var next_month_year = year;
		if (next_month > 12) { next_month=1; next_month_year++; }
		var last_month = month-1;
		var last_month_year = year;
		if (last_month < 1) { last_month=12; last_month_year--; }
		var date_class;
		if (this.type!="WINDOW") {
			result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
			}
		result += '<TR>\n';
		var refresh = windowref+'CP_refreshCalendar';
		var refreshLink = 'javascript:' + refresh;
		if (this.isShowNavigationDropdowns) {
			result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="78" COLSPAN="3"><select CLASS="'+this.cssPrefix+'cpMonthNavigation" name="cpMonth" onChange="'+refresh+'('+this.index+',this.options[this.selectedIndex].value-0,'+(year-0)+');">';
			for( var monthCounter=1; monthCounter<=12; monthCounter++ ) {
				var selected = (monthCounter==month) ? 'SELECTED' : '';
				result += '<option value="'+monthCounter+'" '+selected+'>'+this.monthNames[monthCounter-1]+'</option>';
				}
			result += '</select></TD>';
			result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';

			result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="56" COLSPAN="3"><select CLASS="'+this.cssPrefix+'cpYearNavigation" name="cpYear" onChange="'+refresh+'('+this.index+','+month+',this.options[this.selectedIndex].value-0);">';
			for( var yearCounter=year-this.yearSelectStartOffset; yearCounter<=year+this.yearSelectStartOffset; yearCounter++ ) {
				var selected = (yearCounter==year) ? 'SELECTED' : '';
				result += '<option value="'+yearCounter+'" '+selected+'>'+yearCounter+'</option>';
				}
			result += '</select></TD>';
			}
		else {
			if (this.isShowYearNavigation) {
				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+last_month+','+last_month_year+');">&lt;</A></TD>';
				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="58"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+'</SPAN></TD>';
				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+next_month+','+next_month_year+');">&gt;</A></TD>';
				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';

				result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refreshLink+'('+this.index+','+month+','+(year-1)+');">&lt;</A></TD>';
				if (this.isShowYearNavigationInput) {
					result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><INPUT NAME="cpYear" CLASS="'+this.cssPrefix+'cpYearNavigation" SIZE="4" MAXLENGTH="4" VALUE="'+year+'" onBlur="'+refresh+'('+this.index+','+month+',this.value-0);"></TD>';
					}
				else {
					result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><SPAN CLASS="'+this.cssPrefix+'cpYearNavigation">'+year+'</SPAN></TD>';
					}
				result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refreshLink+'('+this.index+','+month+','+(year+1)+');">&gt;</A></TD>';
				}
			else {
				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+last_month+','+last_month_year+');">&lt;&lt;</A></TD>\n';
				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="100"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+' '+year+'</SPAN></TD>\n';
				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+next_month+','+next_month_year+');">&gt;&gt;</A></TD>\n';
				}
			}
		result += '</TR></TABLE>\n';
		result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=0 CELLPADDING=1 ALIGN=CENTER>\n';
		result += '<TR>\n';
		for (var j=0; j<7; j++) {

			result += '<TD CLASS="'+this.cssPrefix+'cpDayColumnHeader" WIDTH="14%"><SPAN CLASS="'+this.cssPrefix+'cpDayColumnHeader">'+this.dayHeaders[(this.weekStartDay+j)%7]+'</TD>\n';
			}
		result += '</TR>\n';
		for (var row=1; row<=6; row++) {
			result += '<TR>\n';
			for (var col=1; col<=7; col++) {
				var disabled=false;
				if (this.disabledDatesExpression!="") {
					var ds=""+display_year+LZ(display_month)+LZ(display_date);
					eval("disabled=("+this.disabledDatesExpression+")");
					}
				var dateClass = "";
				if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) {
					dateClass = "cpCurrentDate";
					}
				else if (display_month == month) {
					dateClass = "cpCurrentMonthDate";
					}
				else {
					dateClass = "cpOtherMonthDate";
					}
				if (disabled || this.disabledWeekDays[col-1]) {
					result += '	<TD CLASS="'+this.cssPrefix+dateClass+'"><SPAN CLASS="'+this.cssPrefix+dateClass+'Disabled">'+display_date+'</SPAN></TD>\n';
					}
				else {
					var selected_date = display_date;
					var selected_month = display_month;
					var selected_year = display_year;
					if (this.displayType=="week-end") {
						var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0);
						d.setDate(d.getDate() + (7-col));
						selected_year = d.getYear();
						if (selected_year < 1000) { selected_year += 1900; }
						selected_month = d.getMonth()+1;
						selected_date = d.getDate();
						}
					result += '	<TD CLASS="'+this.cssPrefix+dateClass+'"><A HREF="javascript:'+windowref+this.returnFunction+'('+selected_year+','+selected_month+','+selected_date+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+this.cssPrefix+dateClass+'">'+display_date+'</A></TD>\n';
					}
				display_date++;
				if (display_date > daysinmonth[display_month]) {
					display_date=1;
					display_month++;
					}
				if (display_month > 12) {
					display_month=1;
					display_year++;
					}
				}
			result += '</TR>';
			}
		var current_weekday = now.getDay() - this.weekStartDay;
		if (current_weekday < 0) {
			current_weekday += 7;
			}
		result += '<TR>\n';
		result += '	<TD COLSPAN=7 ALIGN=CENTER CLASS="'+this.cssPrefix+'cpTodayText">\n';
		if (this.disabledDatesExpression!="") {
			var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate());
			eval("disabled=("+this.disabledDatesExpression+")");
			}
		if (disabled || this.disabledWeekDays[current_weekday+1]) {
			result += '		<SPAN CLASS="'+this.cssPrefix+'cpTodayTextDisabled">'+this.todayText+'</SPAN>\n';
			}
		else {
			result += '		<A CLASS="'+this.cssPrefix+'cpTodayText" HREF="javascript:'+windowref+this.returnFunction+'(\''+now.getFullYear()+'\',\''+(now.getMonth()+1)+'\',\''+now.getDate()+'\');'+windowref+'CP_hideCalendar(\''+this.index+'\');">'+this.todayText+'</A>\n';
			}
		result += '		<BR>\n';
		result += '	</TD></TR></TABLE></CENTER></TD></TR></TABLE>\n';
	}

	// Code common for MONTH, QUARTER, YEAR
	// ------------------------------------
	if (this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year") {
		if (arguments.length > 0) { var year = arguments[0]; }
		else { 
			if (this.displayType=="year") {	var year = now.getFullYear()-this.yearSelectStartOffset; }
			else { var year = now.getFullYear(); }
			}
		if (this.displayType!="year" && this.isShowYearNavigation) {
			result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
			result += '<TR>\n';
			result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-1)+');">&lt;&lt;</A></TD>\n';
			result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="100">'+year+'</TD>\n';
			result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+1)+');">&gt;&gt;</A></TD>\n';
			result += '</TR></TABLE>\n';
			}
		}
		
	// Code for MONTH display 
	// ----------------------
	if (this.displayType=="month") {
		// If POPUP, write entire HTML document
		result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
		for (var i=0; i<4; i++) {
			result += '<TR>';
			for (var j=0; j<3; j++) {
				var monthindex = ((i*3)+j);
				result += '<TD WIDTH=33% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnMonthFunction+'('+year+','+(monthindex+1)+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+this.monthAbbreviations[monthindex]+'</A></TD>';
				}
			result += '</TR>';
			}
		result += '</TABLE></CENTER></TD></TR></TABLE>\n';
		}
	
	// Code for QUARTER display
	// ------------------------
	if (this.displayType=="quarter") {
		result += '<BR><TABLE WIDTH=120 BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN=CENTER>\n';
		for (var i=0; i<2; i++) {
			result += '<TR>';
			for (var j=0; j<2; j++) {
				var quarter = ((i*2)+j+1);
				result += '<TD WIDTH=50% ALIGN=CENTER><BR><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnQuarterFunction+'('+year+','+quarter+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">Q'+quarter+'</A><BR><BR></TD>';
				}
			result += '</TR>';
			}
		result += '</TABLE></CENTER></TD></TR></TABLE>\n';
		}

	// Code for YEAR display
	// ---------------------
	if (this.displayType=="year") {
		var yearColumnSize = 4;
		result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
		result += '<TR>\n';
		result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-(yearColumnSize*2))+');">&lt;&lt;</A></TD>\n';
		result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+(yearColumnSize*2))+');">&gt;&gt;</A></TD>\n';
		result += '</TR></TABLE>\n';
		result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
		for (var i=0; i<yearColumnSize; i++) {
			for (var j=0; j<2; j++) {
				var currentyear = year+(j*yearColumnSize)+i;
				result += '<TD WIDTH=50% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnYearFunction+'('+currentyear+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+currentyear+'</A></TD>';
				}
			result += '</TR>';
			}
		result += '</TABLE></CENTER></TD></TR></TABLE>\n';
		}
	// Common
	if (this.type == "WINDOW") {
		result += "</BODY></HTML>\n";
		}
	return result;
	}

