//global var that enables alert logging
var logging = false;
var logViaAjax = false;
var logViaAlert = false;
var shortenLogMsg = false;
var initPageOnce = false;
var thickboxIds = new Array();
var loginCookie = null;
var treeCollection = null;
var thickboxWidth=800;
var thickboxHeight=700;

//will generate a 'safe enough' random unique id
function generateUid()
{
  return new Date().getTime() + '' + Math.round(100000000000*Math.random());
}

//specify min of how long status messages can live on a page
var statusTimestamp = 0;
var statusTimeToLive = 10*1024;
var statusMessage = '';

function generateTimestamp()
{
  var timestamp = new Date();
  
  return timestamp.getHours() + ":" + timestamp.getMinutes() + ":" + timestamp.getSeconds() + "." + timestamp.getMilliseconds();
}

function alertLog(msg)
{
   $.prompt(msg);
}

function log(msg)
{
   if (msg.length > 255 && shortenLogMsg)
     msg = msg.substring(0,254);
   var url = '.XmlRequestServlet?handler=com.ud.core.xmlservice.cms.LogService';
   if (logging) 
   {
     msg = generateTimestamp() + " " + msg;
     if (logViaAjax)
     	logAjax(url, msg);
     if (logViaAlert)
        logAlert(msg);
   }
}

function logAlert(msg)
{
  MAX=255*10;
  if (msg.length > MAX)
  {
     alert(msg.substr(0, MAX));
     logAlert(msg.substring(MAX));
  }
  else
    alert(msg);
}

function logAjax(url, msg)
{
  var ajaxExchange = getHTTPObject();
  ajaxExchange.open("POST", url, true);
  ajaxExchange.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  ajaxExchange.send('message=' + escape(msg));
  ////log(msg.substr(msg.length/2 + msg.length/4));
}

var ajaxCount = 0;

//this will redirect the page
function redirect(redirectUrl)
{
  window.location = redirectUrl;
}

function setStatus(msg)
{  
   statusTimestamp = new Date().getTime();
   statusMessage = msg;
   if (document.getElementById('statusMessageDisplay') != null)
   {
      
      $('#statusMessageDisplay').html('<div class="loader" id="statusMessage">&nbsp;</div>');
   	  setTimeout('clearStatus()', statusTimeToLive + 10);
   }
}

function clearStatus()
{
   clearStatusWithForce(false);
}

function clearStatusWithForce(force)
{
    if ((force || statusTimestamp + statusTimeToLive < new Date().getTime() && statusTimestamp != 0) && document.getElementById('statusMessageDisplay') != null)
    {
       //document.getElementById('statusMessageDisplay').innerHTML = '';
       //$('#statusMessageDisplay').empty();
       $('#statusMessageDisplay').empty();
	}
}

//will make an asynchronous ajax call and upon success, will execute the evalCode
function genericCallAjax(url, evalCode)
{
   genericCallAjaxWithXml(url, null, evalCode);
}

function genericCallAjaxWithXml(url, postXml, evalCode)
{
   var postData = 'xml=' + escape(postXml);
   genericCallAjaxWithPost(url, postData, evalCode);
}

function genericCallAjaxWithPost(url, postData, evalCode)
{
  clearStatus();
  
  log('genericCallAjaxWithPost('+url+', '+postData + ', ' +evalCode+')');
  
  showBusyStatus();
  
  var ajaxExchange = getHTTPObject();
  if (ajaxExchange) {
    ajaxExchange.onreadystatechange = function() {
      genericAjaxCallback(ajaxExchange, evalCode);
    };
  }
  
  ajaxExchange.open("POST", url, true);
  
  
  if (postData == null)
 	 ajaxExchange.send('');
  else
  {
    ajaxExchange.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    ajaxExchange.send(postData);
  }
}

//generic callback function for ajax, will execute the eval code upon success
function genericAjaxCallback(ajaxExchange, evalCode)
{
	try
	{
	    if (ajaxExchange == null)
	       throw "ajaxExchange variable is null";

		//log('genericAjaxCallback('+ajaxExchange+', '+evalCode+')');
		if (ajaxExchange.readyState == 4) 
		{
		  if (!(ajaxExchange.status == 200 || ajaxExchange.status == 304)) 
		  {
		    throw('Server Error (genericAjaxCallback): ' + ajaxExchange.status); 
		  }
		  else
		  {
		    //set the global results of the call which may or may not be used in the evalCode
		    var ajaxText = ajaxExchange.responseText;
		    var ajaxXml =  ajaxExchange.responseXML;
		    
		    //if (ajaxText != null)
		      //ajaxText = xmlUnescapeHTMLToXML(ajaxText);
		    
		    log('received response  in genericCallback('+ajaxExchange+', ' +evalCode+')\r\n' + ajaxText);
    
		    //if the nodes are longer than 4096 bits, this will supposedly fix that
		    try
		    {
    		   ajaxXml.normalize();
    		}
    		catch(e2)
    		{
    		}
    		
    		//log('evalCode: ' + evalCode);
    		if (evalCode != null)
		      eval(evalCode);
		  }
		  hideBusyStatus();
		} 
	}
	catch(e)
	{
	   setStatus('An error has occurred and a system administrator has been notified.'); 
	   log('ERROR: ' + e.message);
	}
}


function showBusyStatus()
{
  //log('showBusyStatus');
  setStatus('Updating page...');
  if (document.getElementById('preloader') != null)
  {
  	document.getElementById('preloader').innerHTML = '<img src="../../img/preloader/ploader_fpo.gif" alt="preloader" />';
  }
  ajaxCount++;
  
}

function hideBusyStatus()
{
  //log('hideBusyStatus');
  ajaxCount--;
  if (ajaxCount <= 0)
  {
      if (statusMessage == 'Updating page...')
         clearStatusWithForce(true);
      if (document.getElementById('preloader') != null)
      {
          document.getElementById('preloader').innerHTML = '';//'IDLE ' + generateUid();
      }
  }
}


/* Generic getHTTPObject Function  */
function getHTTPObject() {
  var xhr = false;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    try {
      xhr = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
      try {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
      } catch(e) {
        xhr = false;
      }
    }
  }
  return xhr;
}

function getElementByIdAttr(id, attr)
{
  //log('getElementBy Id with attr');
   
   result = getElementById(id).getAttribute(attr);
   
   //log('getElementById with attribute: ' + result);
   return result;
}

function getElementById(id)
{
   result = document.getElementById(id);
   
   //log('getElementById() : ' + result);
   
   return result;
}

//This function will submit a form and post it to a url via AJAX. The response xml coming back should have an 'id' and 'code' child. The id identifies the div tag to assign the innerHTML to of the 'code' value
function submitAjaxForm(url, formName)
{
  submitModuleForm(url, formName);
}

function setDOMValue(id, val)
{
  getElementById(id).value = val;
}
function initializeSortable(name)
{
  //log('initializeSortable('+name+')');
  Sortable.create(name, {dropOnEmpty:true,containment:[name],constraint:false});
}

function getListOrder(name)
{
   //log('getListOrder('+name+')');
   var result = Sortable.serialize(name, {name: 'key'});
   //log('Serialized result: ' + result);
   return result;
}

//will handle auto delete of a file in a form, prepping the form for submission to a backend that understands this type of exchange
function deleteFile(inputName)
{
   log("deleteFile");
   //get rid of the old hidden delete element
   var id = inputName + "Delete";
   $(id).remove();
   
   //add the hidden form element that will tell the backend to remove the file, also clear the value of the file input
   var element = "<input class=\"hiddenDelete\" type=\"hidden\" id=\""+id+"\" name=\""+id+"\" value=\"delete\"/>";
   $("input[name = '"+inputName+"']").val("").after(element);
   ////log("adding delete: " + id);
   
   
   //in case the class is defined, let's hide any previews
   $("#" + inputName + "Preview").remove();
   //in the case this is a form file, lets remove the button
   $("#" + inputName + "RemoveButton").remove();
   
   //let's remove the 'remove button' from the image input form
   $("#removeButtonIcon" + inputName).hide();
   $("#removeButton" + inputName).hide();
}

function processAjaxFormResponse(responseText, statusText)
{
  alert('Your information has been processed');
}

function processAjaxFormResponseUserManagement(responseText, statusText)
{
   //log('processAjaxFormResponseUserManagement(): ' + responseText);
     
   dom = parseDOM(responseText);
   uid = dom.find("//username/text()") + "";
   isVerified = dom.find("//isVerified/text()") + "";
   role = dom.find("//role/text()") + "";
   cmd = dom.find("//cmd/text()") + "";
   
   
   cls = 'desc user';
   if (role == 'admin' || role == 'RWISO Administrator' || role == 'Website Administrator')
     cls+= '_' + 'admin';
     
   if (isVerified == 'false')
     cls+= '_delete';
   
   //log(cls);
   $("#title" + uid).attr("class", cls);
   
   if (cmd != null && cmd == 'assumeRole')
   {
     $("#assumeUser").remove();
     $("#title" + uid).after("<div id='assumeUser' class='desc assumeUser'>Assumed role</div>");
     //log($("#title" + uid).parent().html());
   }
   else if (cmd != null && cmd == 'deleteUser')
   {
     //uid = dom.find("//input[@name='username']/text()") + "";
     ////log("delete: " + uid);
     $("#userRow" + uid).remove();
     total = Number($("#totalUsers").html()) -1;
     if (total < 0)
      total = 0;
     $("#totalUsers").html(total);
   }
   
}



function initPage()
{
    //this must live outside of the ready function
    initTinyMceForPage(); 
    initCookies();
	      
	$(document).ready(function() {
	
	   
	  
               
                
	  if (!initPageOnce)
	  {
	     initPageOnce=true;
	       
	     
	      
	      initAjaxForms();
	  	  initTooltips();
	  	  
	  	  
	  	  
	  	  initTabs();
	  }
	 
	});
	
}

function deleteCookie(COOKIE_NAME)
{
 $.cookie(COOKIE_NAME, null, { path: '/' });
}

function initCookies()
{
  loginCookie = $.cookie("loginCookie");
  $.cookie('loginCookie', loginCookie, { path: '/' });
}



function initTooltips()
{
	$("a.toolTip").tooltip({
		bodyHandler: function() {
			return $($(this).attr("href")).html();
		},
		showURL: false
	});
}

function initTabs()
{
	//init tabbed panes
	//alert("init tabs");
	$(".tabs").tabs();
	//alert("tabs inited");
}

function initValidationForm(formId)
{
   obj = $("#" + formId);
   obj.submit(function() 
   { 
      msg = "";
	  hasErrors=false;
	  //log(obj.html());
	  obj.find("input[class*='required']").each(function (i, node)
	    {
	      node = $(node);
	     
	      //log(node.attr("name"));
	      if (node.attr("value") == null || node.attr("value").trim() == '')
	        hasErrors = true;
	    });
	  
	  if (hasErrors)
	  {
	     msg += "Please fill out all required fields"; 
	  }
	  
	  //may want to perform other form validation here
	  
	  if (hasErrors)
	  {
	     $("#statusMsg").html("<div class=\"errorMessage\">"+msg + "</div>");
	  }
	  
   
     return !hasErrors; 
   });
}


function initAjaxForms()
{
    var options = { success: processAjaxFormResponse };
    
    
    
        // wait for the DOM to be loaded 
        $(document).ready(function() { 
              // bind 'myForm' and provide a simple callback function 
            $('.ajaxForm').each(function (i, node){
                node = $(node);
                
                //log("init ajax form: " + node.html());
                
                options2 = options;
    
                //see if a custom ajaxHandler is specified for the form
                ajaxHandler = node.find('input[name=\'ajaxHandler\']').val();
                preAjaxHandler = node.find('input[name=\'preAjaxHandler\']').val();
                validationForm = node.find('input[name=\'validationForm\']').val();
                preloadQuery = node.find('input[name=\'preloadQuery\']').val();
                
                //set formid on the form
                
                uid = generateUid();
                //log("initAjaxForms: setting form id to: " + uid + ", form: " + node.html());
                node.attr("id", uid);
                //log("initAjaxForms: form id set to: " + node.attr("id"));
                 
                //as a safety precaution, remove the formId if it exists
                node.find("input[name='formId']").remove();
                idHtml = "<input type=\"hidden\" name=\"formId\" value=\""+uid+"\"/>";
                node.append(idHtml);
                   
                if (preAjaxHandler != null)
                {
                   eval("options2 = { beforeSubmit: "+preAjaxHandler+" }");
                   node.ajaxForm(options2); 
                }
                else if (validationForm != null)
                {
                   //log('ajax form is inited with validation form: ' + validationForm);
                   eval("options2 = { beforeSubmit: beforeSumbitAjaxForm, success: validateForm }");
                   node.ajaxForm(options2); 
                }
                else if (ajaxHandler != null)
                {
                  eval("options2 = { beforeSubmit: beforeSumbitAjaxForm, success: "+ajaxHandler+" }");
                  node.ajaxForm(options2); 
                }        
                
                if (preloadQuery != null)
                {
                   //preload the data
                   loadFormData(uid, preloadQuery);
                }   
             });
        }); 
}

function beforeSumbitAjaxForm()
{
  saveTinyMceData();
  
}

function initTinyMceForPage()
{
	tinyMCE.init({
		mode : "textareas", 
		encoding : "xml",
		theme : "simple",
		theme_advanced_disable : "bold,italic",
		onchange_callback : "saveTinyMceData",
		editor_deselector : "textOnlyTextArea"		
	});	
}

function initTinyMce2()
{
   $("textarea").change(function(){
	  saveTinyMceData();
	})
}

//function saveTinyMceData(data, form)
function saveTinyMceData()
{
    tinyMCE.triggerSave();
  // alert("description1: " + $("textarea[@name='profileDescription2']").val());
   
   //for some reason, the above method does not properly save the values into the textareas, we must query and re-set
   $("textarea").each(function (i, node){
        node = $(node);
        node.val(node.val());
        //name = node.attr("name");
        //alert("textarea("+name+"): " + node.val());
     });
     
  // alert("description2: " + $("textarea[@name='profileDescription2']").val());
}

//TODO some error here causes this function to exit using tree editor on firefox
function loadTinyMceData()
{
  $("textarea[class!='textOnlyTextArea']").each(function (i, node){
        id = node.id;       
        node = $(node);
        if (id != null)
          name = id;
        else
        name = node.attr("name");
        //alert("textarea update: " + name + ", val: " + node.val());
        editor = tinyMCE.get(name);
        if (editor != null)
        {
         
         //alert("loadTinyMceData(): editor.setContent: " + node.val());
         editor.setContent(node.val());
        }
        //tinyMCE.get(name).setContent(node.val());
        //log("after");
     });
  //alert("loadTinyMceData(): description: " + $("textarea[@name='description']").val());
}

function processAjaxFormResponseAddComment(responseText, statusText)
{
  $(".approveMessageHolder").html("<div class=\"approveMessage\"><p>Thank you. Your comment has been submitted for approval.</p></div>").show();
  $("textarea[name='comment']").val("");
  setTimeout('$(".approveMessageHolder").hide().empty()', statusTimeToLive + 10);
}

//will process the validation response, if has errors, will process them. Otherwise be prepared to get anything! If we get HTML back that means the action has been processed
function validateForm(responseText, statusText)
{
   //log('validateForm(): ' + responseText);
   
   //if was posted via textarea in case of file uploads, lets decode to get the true response
   responseText = decodeAjaxResponse(responseText);
   
   //log("validateForm: " + responseText);
   
   //let's see if this is a validation response
   dom = parseDOM(responseText);
   
   //ok valid xml has been received, let's process it
   if (dom.find('//hasErrors/text()') == 'true')
   {
     //validation has failed, let's display the error messages to the user
     //log('validation response');
     applyValidationResult(responseText, dom);
   }
   
   //we are now expecting a 'ajaxRedirect' from the server upon successful validation. We assume the form is already processed, see below else statement
   
   //perhaps there is a javascript method to call
   else if (dom.find('//ajaxPostHandler/text()') != null && (dom.find('//ajaxPostHandler/text()') + '').trim() != '')
   {
      handler = dom.find('//ajaxPostHandler/text()');
      //log('using javascript handler: ' + handler);
      eval(handler+ '(responseText, statusText)');
   }
   else if (dom.find('//ajaxForward/text()') != null && (dom.find('//ajaxForward/text()') + '').trim() != '')
   {
	 //assume the form has been processed and we are redirecting to a simple forwarding result
	 //log("using ajaxForward");
     ajaxForward = xmlUnescapeHTMLToXML("/core" + dom.find('//ajaxForward/text()'));
     //log("redirecting after form processing to: " + ajaxForward);
     redirect(ajaxForward);
   }
   else
   {
	   //default behavior if no forwarding is specified is to simply submit the form based upon an id
	   //we assume the form was not previously processed
	   formId = dom.find('//formId/text()');
	   form = $("input[@value='"+formId+"']").parent();
	    
	   form.find("input[@name='validationForm']").remove();
	   form.unbind();
	   //log("form passed validation, submitting form normally: " + form.html());
	      
	   form.submit();
   }
   
}

function applyValidationResult(responseText, dom)
{
   //first remove previous messages
   $(".validationMessage").remove();
   
   //alert("applyValidationResult: " + responseText);
   
   formId = dom.find("//formId/text()");
   //log("Getting form with formId: " + formId);
   form = $("#" + formId);
   //log("Applying validation messages to: " + form.html());
   
   //apply each error status message for the inputs
   dom.find("//input").each(function (i, node){
       domInput = node;    
       if (domInput.find('@name').currentNode != null)
       {
           name = domInput.find('@name').currentNode.getValue();
           type = domInput.find('@type').currentNode.getValue();
	       
	       message = "";
	       //alert(domInput);
	       domInput.find('validation/message/text()').each(function (i2, node2){ 
	           message += ", " + node2;
	       });
	       if (message.length > 0)
	         message = message.substr(2);
	       formInput = null;
	       if (type.indexOf('extarea') != -1)
	       {
	          formInput = form.find("textarea[@name='"+name+"']");
	       }
	       else
	       {
	          formInput = form.find("input[@name='"+name+"']");
	       }
	       //add the message
	       //log(message);
	       if (message.length > 0)
	       {
	         //alert("Validation msg: " + message);
	         //alert("For: " + formInput.html());
	       	 formInput.parent().after("<dd><div class=\"desc attention validationMessage\">"+message+"</div></dd>");
	       }
	   }
   });
   
   //set the status message of the form
   //log(form.html());
   form.before("<div class=\"errorMessage validationMessage\"><p>Ooops! In order to continue, you must complete the form correctly.</p></div>");
}

function applyHtmlResult(html)
{
   html = xmlEscapeXMLToHTML(html);
   id = generateUid();
   form = "<form action=\"../system/showEscapedHtml.jsp\" id=\""+id+"\" method=\"post\"><textarea name=\"html\">"+html+"</textarea></form>";
   $("body").append(form);
   
   $("#"+id).submit();
}

function decodeAjaxResponse(ajaxText)
{
   //log("decodeAjaxResponse");
   
   if (ajaxText == null || (ajaxText.indexOf('<textarea>') == -1 && ajaxText.indexOf('<TEXTAREA>') == -1))
     return ajaxText;
     
   key = "textarea";
   if (ajaxText.indexOf('<TEXTAREA>') != -1)
     key = "TEXTAREA";
     
   ajaxText = ajaxText.substring(ajaxText.indexOf('<'+key+'>') + 10, ajaxText.lastIndexOf('</'+key+'>'));  
     
   //log("Before: " + ajaxText);
   //ajaxText =  xmlUnescapeHTMLToXML(ajaxText);
   //let's use a different encode/decode
   ajaxText = characterDecode(ajaxText);
   
   //log("After: " + ajaxText);
   
   return ajaxText;
   
}

function characterDecode(str)
{
   result = "";
   eval('result=String.fromCharCode('+str+')');
   //log('decoded: ' + str);
   //log('to: ' + result);
   return result;
}




function submitForm(action, obj)
{
  if (action != null && action == 'yes')
  {
     id = obj.find("div").attr("id");
     //alert("submitForm: " + id);
   
      $("#" + id).find("form").submit();
     
   }
}	

function submitAjaxForm(action, obj)
{
   if (action != null && action == 'yes')
   {
     id = obj.find("div").attr("id");
      $("#" + id).ajaxSubmit();
     
   }
}

//generic form loader based upon simple variable definitions
function loadSimpleForm(url, formId, callback)
{
   if (formId != null)
   {
      //this is needed by loadTreeForm, if not needed here, bump up to parent function
      $("#" + formId).clearForm();
      formId = "\""+formId+"\"";
     
   }
     
   evalCode="applySimpleForm(ajaxText, "+formId+", '"+callback+"')";
   genericCallAjax(url, evalCode);
}

function setFormValue(formId, name, val)
{ 
   //log("setFormValue("+formId+","+name+","+val+")");
   form = $("form[id='"+formId+"']");
   if (form.html() == null)
   {
    //log("form is null");
    form = $("#" + formId).find("form");
   }
  
   form.find("input[name='"+name+"']").val(val);  
   //log(form.html());
}

function applySimpleForm(ajaxText, formId, callback)
{
   //alert("applySimpleForm(): " + ajaxText);
   dom = parseDOM(ajaxText);
   
   //remove delete codes
   $(".deleteCode").remove();
   
   //apply the simple nodes
   dom.find("//*").each(function (i, node){
       name = node.currentNode.getNodeName();
       val = node.find("text()") + "";
       
       //NEW 5/08: decode the stored html if it exists
       val = xmlUnescapeHTMLToXML(val);
       
       if (formId != null)
        form = $("form[id='"+formId+"']");
       else
        form = $("form");
        
       node2 = form.find("input[name='"+name+"']");
       
       if (node2.size() == 0)
         node2 = form.find("textarea[name='"+name+"']");
       if (node2.size() == 0)
         node2 = form.find("select[name='"+name+"']");
       if (node2.size() == 0 && name.endsWith('Filename'))
       {
         name = name.substring(0, name.indexOf('Filename'));
         //alert('trying to locate file name:' + name);
         node2 = form.find("input[name='"+name+"']");
       }
       
         
       if (node2.size() > 0)
       {
         
         type = node2.attr("type");
          if (type == 'textarea')
          {
            val = adjustParsedXml(val);
          }
        if (name != 'forward')
         {
             if (type != 'file')
	         	node2.val(val);
	         else
	         {
	            //protect against case of double entries in forms, happens in tree editor loading edit form
	            //node2.parent().parent().parent().find(".deleteCode").remove();
	            
	            if (node2.parent().parent().find(".deleteCode").length == 0)
	            {
		            //alert('found file on load: ' + name);
		            val = dom.find("//" + name + "Filename/text()") + "";
		            deleteCode = "<dd class=\"deleteCode\"><a id=\""+name+"RemoveButton\" href=\"javascript:void(0)\" onClick=\"deleteFile('"+name+"')\" class=\"desc delete\">Delete</a></dd>";
		            node2.parent().after(deleteCode);
		            
		            deleteCode = "<dl class=\"deleteCode\"><dt><label for=\"preview\">File Link</label></dt><dd></dd><dd><div id=\""+name+"Preview\"><a target=\"new\" href=\""+contentUrl+"/"+val+"\">File Link</a></div></dd></dl>	";
			        node2.parent().parent().after(deleteCode);
		         }
	         }
	         //alert("loaded form element: " + name + ", " + val + ", " + type + ", val: " + node2.val());
         
         }
          
       }
   
   });
   
   //need this here to init thickbox/tinymce on tree editor
   if (callback != null && callback != 'null')
     eval(callback);
   
   
   
   //sync up textboxes with hidden vals
   syncCheckboxes();
   
   //TODO problem here this routine exits on tree editor on firefox
   //sync up interractive text areas
   loadTinyMceData();
}

//we have a scheme for checkboxes that use hidden form elements to send VALUE and NOT_VALUE values to the submit. This function searches for all checkboxes in the forms and then syncs the checked attr based upon the hidden val
function syncCheckboxes()
{
    $('.ajaxForm').each(function (i, node){
       form = $(node);
       form.find("input[type='checkbox']").each(function (i2, node2){
          checkbox  = $(node2);
          name = checkbox.attr("name").replace("Checkbox","");
          val = form.find("input[name='"+name+"']").attr("value");
          
          //log("syncCheckboxes(): " + name+"="+val);
          
           //added val == '' for editNEwsEntry.jsp, when feature box is not checked first time through
           if (val.startsWith("not_") || val == '')
           {
              //log("NOT setting checkbox to true");
              //want to remove checked attribute
              //log("instant checkbox: " + checkbox.attr("checked"));
               //checkbox.attr("checked", "");
           }
           else
           {
              //log("setting checkbox to true");
              checkbox.attr("checked", "true");
           }
           
           //log("checkbox: " + checkbox.attr("checked"));
       });     
    });
}

function initThickbox()
{
    tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox
	//imgLoader = new Image();// preload image
	//imgLoader.src = tb_pathToImage;
}

function initThickboxById(id)
{
    if (thickboxIds[id] == null)
    {
        //alert("thickbox init: " + id);
        thickboxIds[id] = "done";
    	tb_init('#thickbox' + id);//pass where to apply thickbox
		//imgLoader = new Image();// preload image
		//imgLoader.src = tb_pathToImage;
    }
}


//not sure that we should be using this, the more upto date function is loadSimpleForm(url)
//this is used by the 'preloadQuery' parameter of a form so let's integrate this
function loadFormData(formId, query)
{
   url = ".XmlRequestServlet?handler=com.ud.core.formservice.handler.GenericLoaderFH&forward=/www/system/showRawXmlRequest.jsp&xquery=" + query;
   evalCode="applySimpleForm(ajaxText)";
   //removeed legacy link below
   //evalCode="applyFormData(ajaxText)";
   genericCallAjax(url, evalCode);
}

//there is also apply simple form data, be careful this function may not be upto date!
function applyFormData(ajaxText)
{
   ////log("applyFormData(): " + ajaxText);
   dom = parseDOM(ajaxText);
   
   
   //apply the simple nodes
   dom.find("XmlMessage/*").each(function (i, node){
     
       name = node.currentNode.getNodeName();
      // //log(name);
       val = node.find("text()") + "";
       node2 = $("form input[name='"+name+"']");
       if (node2.size() == 0)
         node2 = $("form textarea[name='"+name+"']");
         
       if (node2.size() > 0)
       {
         
         type = node2.attr("type");
         //log("each: " + name + ", " + val + ", " + type);
         if (name != 'forward')
         {
	         if (type != 'file')
	         	node2.val(val);
	         else
	         {
	            val = dom.find("//" + name + "Filename/text()") + "";
	            deleteCode = "<dd><a id=\""+name+"RemoveButton\" href=\"javascript:void(0)\" onClick=\"deleteFile('"+name+"')\" class=\"icon delete\">Delete</a>";
	            node2.parent().after(deleteCode);
	            
	            if (isImg(val))
	            {
		            deleteCode = "<dl><dt><label for=\"preview\">Image Preview</label></dt><dd><div id=\""+name+"Preview\"><img src=\""+contentUrl+"/"+val+"\" width=\"50\"/></div></dd></dl>	";
		            //log(deleteCode);
		            node2.parent().parent().after(deleteCode);
	            }
	            else
	            {
	            	deleteCode = "<dl><dt><label for=\"preview\">File Link</label></dt><dd><div id=\""+name+"Preview\"><a target=\"_blank\" href=\""+contentUrl+"/"+val+"\">File Link</a></div></dd></dl>	";
		            //log(deleteCode);
		            node2.parent().parent().after(deleteCode);
	            }
	         }
         }
       }
   
   });
}



function isImg(f)
{
  if (f == null)
     return false;
  if (f.endsWith('.gif') || f.endsWith('.jpg') || f.endsWith('.tiff') || f.endsWith('.png') || f.endsWith('.bmp'))
     return true;
   return false;
}

function syncCheckbox(id)
{
   checked = $("#" + id +":checked").length;
   
   val = $("#" + id).val();
   if (checked == 0)
   {
     val = "not_" + val;
   }
   
   $("input[name='"+id+"']").attr("value", val);
   
   //alert("syncCheckbox: " + $("input[name='"+id+"']").val());
}


// When we get an escaped entry back from the server, the dom parser will parse it as inline text. However, the &quot; (") characters are encountered in line and thus must be replaced as ", not &quot;
//There may need to be other adjustments, will make them here as we encounter them
function adjustParsedXml(str)
{
   if (str == null)
   return str;
   
   return str.replace(/&quot;/g, "\"");
}

function disableTinyMce(id)
	 {	
	     $("#" + id).find("textarea[class!='textOnlyTextArea']").each(function (i, node){
	        //id=node.id;
	        nodeOrig=node;
	        node = $(node);
	        node.val(node.val());
	        name = node.attr("name");
	        
	        
	       
	        if (nodeOrig.id == '')
	          nodeOrig.id=id +'_'+name;
	        
	        id=nodeOrig.id;
	        
	        try
	        {
		        //alert("removing: '" + id + "'");
		        tinyMCE.execCommand( 'mceRemoveControl', true, id);  
	        }
			catch(e)
			{
			 //alert("Exception for " + id + ": " + e);
			}
			
			
			 
	    }); 
     }
     
     function enableTinyMce(id)
	 {	
	      tinyMCE.idCounter=0;
	      $("#" + id).find("textarea[class!='textOnlyTextArea']").each(function (i, node){
	        //id=node.id;
	        nodeOrig=node;
	        node = $(node);
	        node.val(node.val());
	        name = node.attr("name");
	        
	        
	       
	        if (nodeOrig.id == '')
	          nodeOrig.id=id+'_'+name;
	        
	        id=nodeOrig.id;
	        
	       try
			{
		        //alert("reiniting: " + id);
				tinyMCE.execCommand( 'mceAddControl', true, id);
			}
			catch(e)
			{
			   //alert("Exception for " + id + ": " + e);
			}
			
			
			 
	    }); 
	    //alert('exit enableTinyMce(): ' + id);
     }
     
function loadTreeForm(nodeId, divFormId)
{
  if (divFormId == null)
    divFormId = "editForm";
    
    
  //log('loadTreeForm(): divFormId: ' + divFormId);
    
  url = ".XmlRequestServlet?handler=com.ud.core.formservice.handler.GenericLoaderFH&amp;forward=/www/system/showRawXmlRequest.jsp&amp;nodeId="+nodeId+"&amp;xquery=collection(\'"+treeCollection+"\')//node[@id=\'"+nodeId+"\']/data";
  //log("loadTreeForm(): " + url);
  formId = $('#' +divFormId ).find('form').attr('id');
  
  //need to disable tinyMCE prior to loading it in thickbox, bug in Firefox on windows
  disableTinyMce(divFormId);
  
  callbackFunction = "initThickboxTinyMce()";
  loadSimpleForm(url, formId, callbackFunction);
}

//user for addForm, does not neet to load variables
function initTreeForm(nodeId, divFormId)
{
  if (divFormId == null)
    divFormId = "editForm";
    
    
  //alert('loadTreeForm(): divFormId: ' + divFormId);
    
  //url = ".XmlRequestServlet?handler=com.ud.core.formservice.handler.GenericLoaderFH&amp;forward=/www/system/showRawXmlRequest.jsp&amp;nodeId="+nodeId+"&amp;xquery=collection(\'/db/websites/"+website+"/data/faq')//node[@id=\'"+nodeId+"\']/data";
  //alert("loadTreeForm(): " + url);
  formId = $('#' +divFormId ).find('form').attr('id');
  
  //clear the form
  $("#" + formId).clearForm();
  
  //need to disable tinyMCE prior to loading it in thickbox, bug in Firefox on windows
  disableTinyMce(divFormId);
  
  $("#" + formId).clearForm();
  
  
  callbackFunction = "initThickboxTinyMce()";
  
  //init the tiny mce form after 2 seconds
  setTimeout(callbackFunction, 2000);
  //loadSimpleForm(url, formId, callbackFunction);
}

function initThickboxTinyMce()
{
    //alert("initThickboxTinyMce()");
    enableTinyMce('TB_window');
}

//will activate if global var doRefreshTinyMceFromThickbox is set to true
//this function refreshes tiny mce when a scroll event fires from thickbox
function initThickboxScrollHandler()
{
   $("#TB_ajaxContent").scroll(function () { 
				   refreshThickboxTinyMce();			
    });
}

var refreshTBTimestamp = 0;
function refreshThickboxTinyMce()
{
  
  if (new Date().getTime() > refreshTBTimestamp)
  {
      //alert("refreshThickboxTinyMce()");
      refreshTBTimestamp = new Date().getTime() + 200;
	  cleanupThickboxTinyMce();
	  initThickboxTinyMce();
  }
}

function cleanupThickboxTinyMce()
{
    //alert("cleanupThickboxTinyMce()");
    disableTinyMce('TB_window');
    //alert("after cleanupThickboxTinyMce()");
}


//tree editor functions
function initTree(treeCollectionIn, treeFormCollectionIn)
{
  treeCollection = treeCollectionIn;
  var treeFormCollection = treeFormCollectionIn;
  
  $('#treeAdmin').fileTree({ root: '/0', script: '/core/www/tree/getNode.jsp?thickBoxWidth='+thickboxWidth+'&thickboxHeight='+thickboxHeight+'&formCollection='+treeFormCollection+'&collectionIn=' + treeCollection });
	
}

function initSort(id)
{
  //log("initSort");
  $('#' + id).find("ul").sortable({ items: "li", revert: true, tree: true, stop:stopSort, containment: '#' + id });
  disableSort(id);
}

function stopSort(e, ui)
{
  disableSort('treeAdmin');
}

function moveTreeItemServer(id, action)
{
   //alert('moveTreeItemServer('+id+','+action+')');
   //use treeCollection global var
   url = ".XmlRequestServlet?handler=com.ud.core.formservice.handler.tree.TreeFH&amp;forward=/www/system/showRawXmlRequest.jsp&amp;collection=" + treeCollection + "&amp;nodeId=" + id + "&amp;action=" + action;
   evalCode="moveTreeItemServerCallback(ajaxText)";
   //alert(url);
   genericCallAjax(url, evalCode);
}

function moveTreeItemServerCallback(ajaxText)
{
   //alert("server processed cmd: " + ajaxText);
}

function moveTreeItem(id, action)
{
  try
  {
	  node = $('#treeItem' + id);
	  //alert("moveTreeItem(): " + id + ", " + action);
	  
	  
	  if (action == 'down')
	  {
	    node.next().after(node);
	  }
	  if (action == 'up')
	  {
	    node.prev().before(node);
	  }
	  if (action == 'left')
	  {
	    par = node.parent().parent();
	    if (par.get(0).nodeName == 'li' || par.get(0).nodeName == 'LI')
	   		par.after(node);
	  }
	  if (action == 'right')
	  {
	    par = node.prev();
	    if (par.get(0).nodeName == 'li' || par.get(0).nodeName == 'LI')
	    {
	        if (par.find("ul:first").length == 0)
	        par.append("<ul class=\"jqueryFileTree\" style=\"display: none;\"></ul>");
	        
	    	par.find("ul:first").append(node);
	    }
	  }
	}
	catch(e)
	{
	}
	  
	moveTreeItemServer(id, action);
}

function enableSort(id)
{
  initSort(id);
  //log("enableSort");
  $('#' + id).find("ul").sortable("enable");
}
function disableSort(id)
{
  //log("disableSort");
  $('#' + id).find("ul").sortable("disable");
}
		
		

//init code for javascript enhancements
if ( !(new String).trim ){	String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,''); };}	
if ( !(new String).normalize && (new String).trim ){	String.prototype.normalize = String.prototype.normalise = function() { return this.trim().replace(/\s+/g,' '); };}	
if ( !(new String).startsWith ){	String.prototype.startsWith = function(str,i){ i=(i)?'i':'';var re=new RegExp('^'+str,i);return (this.normalize().match(re)) ? true : false ; };}	
if ( !(new String).endsWith ){	String.prototype.endsWith = function(str,i){ i=(i)?'gi':'g';var re=new RegExp(str+'$',i);return (this.normalize().match(re)) ? true : false ; };}



