// 1.1.49e
/* First line must show version number - update as builds change


History:
  (older history - see ./functions_changelog.txt)
1.1.49 (2008-07-31)
  1) Tiny change to document_reader() to deal with IE's double-margin bug
  2) Added print_form_data()
  3) Change to geid_val() for checkbox - now returns value of field only if checked
1.1.48 (2008-07-24)
  1) Various changes for people with MUCH older browsers - added four array method prototypes
  2) Bug fix for ajax report updates for sites whose basepath is NOT /
  3) Bug fix for NS 6.2 which doesn't know about conditional compilation in ajax_post() and include() -
     had fault in comment delimiters for this section
  4) Added document_reader(), document_reader_get_page_name() and document_reader_goto_page()
1.1.47 (2008-07-09)
  1) Fine tuning ajax_config_display()
1.1.46 (2008-07-08)
  1) Added global array ajax_controls to hold xHTTP object pointers to allow for ajax abort controls that are pending
  2) Implemented automatic pending request abort for ajax_post() and include() functions -
     if connection is active for the destination div and a new request comes in, old one is aborted
  3) Added ajax_config_display() to allow for much simplified remote config display without sajax library
1.1.45 (2008-07-05)
  1) More support added for ajax_report - can now show / hide email addresses in div-based refresh
  2) In order to retain functionality with views OTHER than ajax-based reports, e.g. Version History
     report on Ecclesiact site, all handlers for paging and filters now default back to form submit mode
     if report_name wasn't passed as a parameter - this allows fallback compatability mode for such pages
  3) Better layout of loading mask for ajax_div_loading()
  4) Context Menus fixed if enabled after ajax report refresh
1.1.44 (2008-07-02)
  1) New function ajax_report(reportID,report_name,toolbar) for doing ajax report updates
1.1.43 (2008-07-01)
  1) Extended externalLinks() to also add target='_blank' for rss-item links
1.1.42 (2008-06-26)
  1) More changes to comments() to support status changes
  2) Changes to Tooltips code to allow it to be initialised once page has loaded
1.1.41 (2008-06-25)
  1) Added ajax_post() - very similar to include() but with additional xParams
  2) Modified comments() to take additional parameters pertaining to item being commented on
     and to use ajax_post() function to post data to server
1.1.40 (2008-06-20)
  1) Big changes to attach_field_behaviour) for type 'seq' - now uses icons for +/- and no document.write
     and removed support for qty - now handled in codebase 
1.1.39 (2008-06-17)
  1) Added search_setup_date_range()
  2) Added lead_zero()
  3) Added date_selector_draw() and date_selector_onchange()
  4) Tweak to search_results_go() to set non-available fields to "" instead of "false"
1.1.38 (2008-06-11)
  1) Tweak to externalLinks() to have it also set anchor disabled flag to true if rel='disabled'
1.1.37 (2008-06-10)
  1) Added match_picture() function to simplify input validation
  2) Changes to attach_field_behaviour() for date to remove automatic insertion of '-' which made backspace a real pain
  3) Extended attach_field_behaviour() to include support for datetime
1.1.36 (2008-06-06 - replaced in same build with 1.1.37)
  1) print_friendly() now includes support for search_categories and search_keywords
  2) search_results_go() now includes support for search_categories
1.1.35 (2008-06-02)
  1) Changes to selector_csv_show() to perform selection based on case-insensitive text matching 
1.1.34 (2008-05-29)
  1) Added function comment()
1.1.33 (2008-05-28)
  1) Changed progress indicator in poll() for one that looks more 'ajaxy'
1.1.32 (2008-05-27)
  1) Bug fix for print_friendly() to correctly handle postings when nice URLs are used rather than IDs (weas broken)
  2) Improved URL for print_form() for friendly URLs
  3) Support added for polling
1.1.31 (2008-05-20)
  1) New function open_item(type,ID,page) -
     opens a posting OR page and uses friendly paths if enabled to do so
1.1.30 (2008-05-14)
  1) No longer reports geid_val error for other field types
  2) Improvements to geid() for firefox
  3) Tweak to attach_field_behaviour() for posting_name to replace ' - ' with single '-'
1.1.29 (2008-05-12)
  1) Added new function externalLinks() for XHTML strict method to replace target=_blank with rel='external' on links
  2) var popup_msg now set here not in codebase
  3) Function version() now assumes friendly URLs for build version
  4) Change to geid() to also test for radio button collections in firefox - thanks James!
1.1.28 (2008-05-01)
  1) Added new behaviour for posting_name in attach_field_behaviour()
1.1.27 (2008-04-14)
  1) Bug fix for view_credit_memo() path
  2) Several functions now respect use_friendly_urls flag:
       print_form()
       view_event_registrants()
       view_credit_memo()
       view_order_details()
1.1.26 (2008-04-04)
  1) Changed references to ./ to use base_url variable instead
  2) Removed read_more() function (not used)
1.1.25 (2008-03-22)
  1) Added search_go() - topbar_search_go() now calls this instead.
  2) search_text now used internally, topbar_search feeds into this instead
  3) Changes to selector_csv_show() to reference text on tooltip, not value - now sets colours also
1.1.24 (2008-03-16)
  1) Changes to topbar_search_go() to also reset search_offset value when called
  2) Added search_offset() to simplify search results paging
  3) Changes to print_friendly() to include params for search_offset if given
  4) Added search_results_go()
1.1.23 (2008-03-01)
  1) Bug fix for YYYY-MM-DD date mask to prevent misreading as octal values - changed parseInt to parseFloat
  2) further bg fix for YYYY-MM-DD date mask to allow yyyy to equal 0000 for repeating events
  3) show_popup_screensize() now takes valid sizes as an array passed by reference
1.1.22 (2008-02-25)
  1) Added print_form()
1.1.21 (2008-02-23)
  1) Changes to selector_csv_show() selector_csv_delete() and selector_csv_add() to reset
     selector after adding new options and to re-apply nice tooltips after updates
1.1.20 (2008-02-21)
  1) Added input mask testing for valid dates in attach_field_behaviour()
  2) Added input mask testing for valid hh:mm values in attach_field_behaviour()
  3) Bug fix by James to prevent unwanted keypresses working in Mozilla
  4) Change to add_btns() to allow multiple buttons to be active and remember their settings - used for global navs

*/

// ************************************
// * Browser detection:               *
// ************************************
var isNS4 =	(navigator.appName.indexOf("Netscape")>=0 && !document.getElementById) ? true : false;
var isIE4 =	(document.all && !document.getElementById) ? true : false;
var isIE5 =	(document.getElementById && document.all) ? true : false;
var isNS6 =	(document.getElementById && navigator.appName.indexOf("Netscape")>=0 ) ? true : false;
var isW3C =	(document.getElementById && 1) ? true : false;

var popup_msg =	'';
var ajax_controls = [];

// These are for browsers with JS < 1.2 such as IE5
undefined = void 0;

//not working for Mozilla
/*
if (!Array.prototype.shift) {
  Array.prototype.shift = function() {
    var temp = this[0];
    this = this.slice(1);
    return temp;
  }
}

if (!Array.prototype.unshift) {
  Array.prototype.unshift = function(e) {
    var temp = new Array();
    temp.concat(e, this);
    this = temp.slice(0);
    return this.length;
  }
}
*/
if (!Array.prototype.pop) {
  Array.prototype.pop = function() {
    var temp = this[this.length-1];
    this.length--;
    return temp;
  }
}

if (!Array.prototype.push) {
  Array.prototype.push = function(item) {
    this[this.length] = item;
    return this.length;
  }
}

if(typeof encodeURIComponent != "function") {
  encodeURIComponent = function(str){
    var decVals = ["%",'"'," ","<",">","\\[","\\]","\\\\","\\^","~","\\{","\\}","\\|","\\:",";","#","\\$","&",",","/","=","\\?","@"];
    var encVals = ["%25","%22","%20","%3C","%3E","%5B","%5D","%5C","%5E","~","%7B","%7D","%7C","%3A","%3B","%23","%24","%26","%2C","%2F","%3D","%3F","%40"];
    for(var i=0;i<decVals.length;i++){
       document.title = decVals[i];
       var re = new RegExp(decVals[i],"gi");
       str = str.replace(re,encVals[i]);
    }
    return str;
  }
}

// ************************************
// * externalLinks                    *
// ************************************
// Ref: http://www.sitepoint.com/article/standards-compliant-world/3
function externalLinks() { 
  if (!document.getElementsByTagName) return; 
  var anchors = document.getElementsByTagName("a"); 
  for (var i=0; i<anchors.length; i++) { 
    var anchor = anchors[i]; 
    if (anchor.getAttribute("href") && 
        anchor.getAttribute("rel") == "external") 
      anchor.target = "_blank";
    if (anchor.className=='rss-item')
      anchor.target = "_blank";
    if (anchor.getAttribute("href") && 
        anchor.getAttribute("rel") == "disabled") 
      anchor.disabled = true; 
  } 
}

// ************************************
// * getElementById() aliases         *
// ************************************
function geid(id) {
  if(typeof(id)=='string' && id!='') {
    if (document.getElementById(id)) {
      return document.getElementById(id);
    }
    if (document.getElementById('form') && document.getElementById('form').elements[id]){
      return document.getElementById('form').elements[id];
    }
    return null;
  }
  return id;
}

function geid_val(id) {
  // FF fails on getElementByID where ID is one of several
  var obj, element_arr;
  obj = geid(id);
  if (obj && typeof obj.type !='undefined'){
    switch (obj.type) {
      case 'checkbox':
        return (obj.checked ? obj.value : '')
      break;
      case 'file':
      case 'hidden':
      case 'password':
      case 'text':
      case 'textarea':
        return obj.value;
      break;
      case 'radio':
        return radio_group_get(id);
      break;
      case 'select-one':
        return obj.options[obj.selectedIndex].value;
      break;
    }
  }
  if (document.getElementsByName) {
    element_arr = document.getElementsByName(id);
    if (typeof element_arr[0]=='undefined') {
      return false;
    }
    switch (element_arr[0].type) {
      case 'radio':
        return radio_group_get(id);
      break;
    }
  }
//  alert("Error:\ngeid_val('"+id+"') found unhandled object type "+element_arr[0].type);
  return obj.value;
}
function geid_set(id,value) {
  // FF fails on getElementByID where ID is one of several
  var obj, element_arr;
  obj = geid(id);
  if (obj && typeof obj.type !='undefined'){
    switch (obj.type) {
      case 'checkbox':
        obj.checked = value;
        return true;
      break;
      case 'file':
      case 'hidden':
      case 'password':
      case 'text':
      case 'textarea':
        obj.value = value;
        return true;
      break;
      case 'radio':
        alert('Cannot set radio using this function yet');
        return false;
      break;
      case 'select-one':
        var n;
        for (var n=0; n<obj.length; n++){
          if (obj.options[n].value==value) {
            obj.selectedIndex = n;
            return true;
          }
        }
        return false;
      break;
    }
  }
  alert("Error:\ngeid_set('"+id+"') found unhandled object type "+element_arr[0].type);
  return false;

}
// ************************************
// * Input validation                 *
// ************************************
function match_picture(picture,val) {
  for (i=0; i<picture.length; i++){
    if (val.length<=i) {
      break;
    }
    switch(picture.substr(i,1)) {
      case "0":
        rexp = /[\d]/;
        if (!rexp.test(val.substr(i,1))){
          return val.substr(0,i);
        }
      break;
      case "-":
        rexp = /[\-]/;
        if (!rexp.test(val.substr(i,1))){
          return val.substr(0,i)+"-";
        }
      break;
      case " ":
        rexp = /[ ]/;
        if (!rexp.test(val.substr(i,1))){
          return val.substr(0,i)+" ";
        }
      break;
      case ":":
        rexp = /[\:]/;
        if (!rexp.test(val.substr(i,1))){
          return val.substr(0,i)+":";
        }
      break;
    }
  }
  return val
}


function attach_field_behaviour(id,type,args) {
  var obj, fn, val, yyyy, mm, dd, dash, leap, _hh, _mm, i;
  var pattern, rexp;

  obj = geid(id);
  if (!obj) {
    return;
  }
  switch (type){
    case 'currency':
    case 'currency_s':
      fn = function(e){
        val = geid(id).value;
        if (typeof args!='undefined' && typeof args['min']!='undefined') {
          val = (val < args['min'] ? args['min'] : val);
        }
        if (typeof args!='undefined' && typeof args['max']!='undefined') {
          val = (val > args['max'] ? args['max'] : val);
        }
        geid(id).value=two_dp(val);
        if (typeof geid(id).onchange=='function'){
          geid(id).onchange();
        }
      } 
      addEvent(obj, "blur", fn); 
    break;
    case 'date':
    case 'datetime':
      fn = function(e){
        val = match_picture('0000-00-00 00:00',geid_val(id).toString());
        if (val.length>=4) {
          yyyy = parseFloat(val.substr(0,4));
          leap = ((yyyy%4==0) && (yyyy%100!=0)) || (yyyy%400==0);
          if (yyyy!=0 && yyyy<1900) {
            geid_set(id,'1900');
            return;
          }
          if (yyyy>2100) {
            geid_set(id,'2100');
            return;
          }
        }
        if (val.length>=7) {
          mm = parseFloat(val.substr(5,2));
          if (mm<1) {
            geid_set(id,val.substr(0,5)+'01');
            return;
          }
          if (mm>12) {
            geid_set(id,val.substr(0,5)+'12');
            return;
          }
        }
        if (val.length>=10) {
          dd = parseFloat(val.substr(8,2));
          if (dd<1) {
            geid_set(id,val.substr(0,8)+'01');
            return;
          }
          if (!leap && mm==2 && dd>28) {
            geid_set(id,val.substr(0,8)+'28');
            return;
          }
          if (leap && mm==2 && dd>29) {
            geid_set(id,val.substr(0,8)+'29');
            return;
          }
          if ((mm==4 ||  mm==6 || mm==9 || mm==11) && dd>30) {
            geid_set(id,val.substr(0,8)+'30');
            return;
          }
          if (dd>31) {
            geid_set(id,val.substr(0,8)+'31');
            return;
          }
        }
        if (val.length>=13) {
          _hh = parseFloat(val.substr(11,2));
          if (_hh<1) {
            geid_set(id,val.substr(0,11)+'00');
            return;
          }
          if (_hh>23) {
            geid_set(id,val.substr(0,11)+'23');
            return;
          }
        }
        if (val.length>=16) {
          _mm = parseFloat(val.substr(14,2));
          if (_mm<1) {
            geid_set(id,val.substr(0,14)+'00');
            return;
          }
          if (_mm>59) {
            geid_set(id,val.substr(0,14)+'59');
            return;
          }
        }
        if (val.length>=19) {
          _ss = parseFloat(val.substr(17,2));
          if (_ss<1) {
            geid_set(id,val.substr(0,17)+'00');
            return;
          }
          if (_ss>59) {
            geid_set(id,val.substr(0,17)+'59');
            return;
          }
        }
        geid_set(id,val);
      }
      addEvent(obj, "keyup", fn); 
    break;
    case 'hh:mm':
      fn = function(e){
        val = match_picture('00:00',geid_val(id).toString());
        if (val.length>=1) {
          var hh_10 = parseInt(val.substr(0,1));
          if (hh_10>2) {
            geid_set(id,'2'+val.substr(1));
            return;
          }
        }
        if (val.length>=2) {
          var hh_1 = parseInt(val.substr(1,1));
          if (hh_10==2 && hh_1>3) {
            geid_set(id,val.substr(0,1)+'3'+val.substr(2));
            return;
          }
        }
        if (val.length>=4) {
          var mm_10 = parseInt(val.substr(3,1));
          if (mm_10>5) {
            geid_set(id,val.substr(0,3)+'5');
            return;
          }
        }
        geid_set(id,val);
      }
      addEvent(obj, "keyup", fn); 
    break;
    case 'posting_name':
      fn =
        function(e){
          if (geid(id) && geid_val(id)=='' && geid('title')){
            geid_set(id,geid_val('title'));
          }
          var name = geid_val(id).toLowerCase().replace(/ - /g,'-').replace(/ /g,'-').replace(/[^0-9\-a-zA-Z\(\)\%]/g,'');
          geid_set(id,name);
        };
      addEvent(window,'load',fn);
      addEvent(geid(id), "change", fn);
      addEvent(geid('title'), "change", fn);
    break;
    case 'qty':
      // Up button:
      fn = function(e){geid(id).value=parseInt(geid(id).value)+1;geid(id).onchange();}
      addEvent(geid(id+'_up'), "click", fn);
      fn = function(e){geid(id+'_up').style.backgroundPosition='-1434px 0px'}
      addEvent(geid(id+'_up'), "mouseover", fn);
      fn = function(e){geid(id+'_up').style.backgroundPosition='-1423px 0px'}
      addEvent(geid(id+'_up'), "mouseout", fn);


      // Down button:
      fn = function(e){if (parseInt(geid(id).value)>0){geid(id).value=parseInt(geid_val(id))-1;geid(id).onchange();}}
      addEvent(geid(id+'_down'), "click", fn);
      fn = function(e){if (parseInt(geid(id).value)>0){geid(id+'_down').style.backgroundPosition='-1434px 8px'}}
      addEvent(geid(id+'_down'), "mouseover", fn);
      fn = function(e){if (parseInt(geid(id).value)>0){geid(id+'_down').style.backgroundPosition='-1423px 8px'}}
      addEvent(geid(id+'_down'), "mouseout", fn);


      switch (parseInt(obj.value)){
        case 0:
          geid(id+'_down').style.backgroundPosition='-1445px 8px';
        break;
        default:
          geid(id+'_down').style.backgroundPosition='-1423px 8px';
        break;
      }
    break;

    case 'readonly':
      obj.style.backgroundColor='#f0f0f0';
      obj.style.color='#404040';
      fn = function(e){this.blur();}; 
      addEvent(obj, "focus", fn);
    break;

    case 'seq':
      if (geid_val('ID')) {
        geid(id).style.backgroundColor="";
        geid(id+'_up').style.backgroundPosition='-1423px 0px';
        switch (parseInt(obj.value)){
          case 0:
          case 1:
          break;
          default:
            geid(id+'_down').style.backgroundPosition='-1423px 8px';
          break;
        }
      }   

      // Up button:
      fn = function(e){
        if (geid_val('ID')){
          geid(id).style.backgroundColor='#e8e8e8';
          geid(id+'_up').onclick=null;
          geid(id+'_up').onmouseover=null;
          geid(id+'_up').onmouseout=null;
          geid(id+'_down').onclick=null;
          geid(id+'_down').onmouseover=null;
          geid(id+'_down').onmouseout=null;
          geid('targetField').value=id;
          geid('targetValue').value=parseInt(geid(id).value)+1;
          geid('submode').value='seq_up';
          geid(id+'_up').style.backgroundPosition='-1445px 0px';
          geid(id+'_down').style.backgroundPosition='-1445px 8px';
          geid('form').submit();
        }
      }
      geid(id+'_up').onclick=fn;

      fn = function(e){
        if (geid_val('ID')) {
          geid(id+'_up').style.backgroundPosition='-1434px 0px';
        }
      }
      geid(id+'_up').onmouseover=fn;

      fn = function(e){
        if (geid_val('ID')) {
          geid(id+'_up').style.backgroundPosition='-1423px 0px';
        }
      }
      geid(id+'_up').onmouseout=fn;

      // Down button:
      fn = function(e){
        if (geid_val('ID') && parseInt(geid(id).value)>0){
          geid(id).style.backgroundColor='#e8e8e8';
          geid(id+'_up').onclick=null;
          geid(id+'_up').onmouseover=null;
          geid(id+'_up').onmouseout=null;
          geid(id+'_down').onclick=null;
          geid(id+'_down').onmouseover=null;
          geid(id+'_down').onmouseout=null;
          geid('targetField').value=id;
          geid('targetValue').value=parseInt(geid(id).value)-1;
          geid('submode').value='seq_down';
          geid(id+'_up').style.backgroundPosition='-1445px 0px';
          geid(id+'_down').style.backgroundPosition='-1445px 8px';
          geid('form').submit();
        }
      }
      geid(id+'_down').onclick=fn;

      fn = function(e){
        if (geid_val('ID') && parseInt(geid(id).value)>0){
          geid(id+'_down').style.backgroundPosition='-1434px 8px'
        }
      }
      geid(id+'_down').onmouseover=fn;

      fn = function(e){
        if (geid_val('ID') && parseInt(geid(id).value)>0){
          geid(id+'_down').style.backgroundPosition='-1423px 8px';
        }
      }
      geid(id+'_down').onmouseout=fn;
    break;

    case 'swatch':
      obj.value=obj.value.toUpperCase();
    break;
  }
  fn = function(e){return keytest(e,type,obj);} 
  addEvent(obj, "keypress", fn); 
}

  
function keytest(e,type,obj){
  var keynum, keychar, rexp, ok, value, delete2;
  rexp = false;
  if (window.event) {
    keynum = e.keyCode;
  }
  else {
    keynum = e.which;
  }
  keychar = String.fromCharCode(keynum);
  switch (type) {
    case 'currency':
      rexp = /[\d\.\-]/;
    break;
    case 'currency_s':
      rexp = /[\d\.]/;
    break;
    case 'date':
      rexp = /[\d\-]/;
    break;
    case 'datetime':
      rexp = /[\d\-\: ]/;
    break;
    case 'hh:mm':
      rexp = /[\d\:]/;
    break;
    case 'int':
    case 'seq':
      rexp = /[\d\-]/;
    break;
    case 'int_s':
      rexp = /[\d]/;
    break;
    case 'posting_name':
      rexp = /[\d\-a-zA-Z\(\)]/;
    break;
    case 'qty':
      rexp = /[\d]/;
    break;
    case 'percent':
      rexp = /[\d\.]/;
    break;
    case 'swatch':
      if (e.keyCode>96 && e.keyCode<122){
        e.keyCode-=32;
      }
      rexp = /[\dabcdefABCDEF]/;
    break;
    default:
//      alert(type+' is not handled');
    break;
  }
  var result = rexp!==false && rexp.test(keychar);
  if (!result && e.preventDefault) {
    switch (e.keyCode) {
      case 8: case 27: case 37: case 38: case 39: case 40: case 46:
      break;
      default: 
        e.preventDefault();
      break;
    }
  }
  return result;
}

function comment(mode,ID,submode,commentID) {
  var obj,js,pw;
  pw =
     "<img class='fl' src='"+base_url+"img/?mode=sysimg&img=progress_indicator.gif' width='16' height='16' alt='Please wait...'>"
    +"<div class='fl' style='color:#808080'><em>&nbsp;Loading... Please Wait</em></div><div class='clr_b'></div>";
  switch (submode){
    case "cancel":
      geid('comment_button_cancel').disabled=true;
      geid('comment_button_submit').disabled=true;
      if (geid_val('comment_text') + geid_val('captcha_key') == '' || confirm('Really cancel? Your changes will be lost.')){
        window.focus();
        geid('comment_new').innerHTML="<p><a href=\"javascript:void comment('"+mode+"','"+ID+"','new')\">Add Comment</a></p>";
      }
      else {
        geid('comment_button_cancel').disabled=false;
        geid('comment_button_submit').disabled=false;
      }
      return false;
    break;
    case "delete":
      return comment_delete(mode,ID,commentID);
    break;
    case "edit":
      window.focus();
      xFn = function() { comment_get_count(mode,ID) };
      include(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode='+submode+'&commentID='+commentID,'comment_'+commentID,xFn);
      return false;
    break;
    case "mark_approved":
      return comment_mark(mode,ID,commentID,'approved');
    break;
    case "mark_pending":
      return comment_mark(mode,ID,commentID,'pending');
    break;
    case "mark_spam":
      return comment_mark(mode,ID,commentID,'spam');
    break;
    case "new":
      window.focus();
      geid('comment_new').innerHTML=pw;
      include(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode='+submode,'comment_new');
      return false;
    break;
    case "post":
      window.focus();
      geid('comment_button_cancel').disabled=true;
      geid('comment_button_submit').disabled=true;

      var abort = false;
      geid('th_comment_name').style.color = 	(geid_val('comment_name')=='' ? '#ff0000' : '');
      geid('th_comment_email').style.color =	(geid_val('comment_email')=='' ? '#ff0000' : '');
      geid('th_comment_text').style.color =	(geid_val('comment_text')=='' ? '#ff0000' : '');
      geid('th_captcha_key').style.color =	(geid_val('captcha_key')=='' ? '#ff0000' : '');

      if (geid_val('comment_name')=='' || geid_val('comment_email')=='' || geid_val('comment_text')=='' || geid_val('captcha_key')=='') {
        abort=true;
      }
      if (abort){
        alert('Missing fields');
        geid('comment_button_cancel').disabled=false;
        geid('comment_button_submit').disabled=false;
      }
      else {
        window.focus();
        post_vars =
          "comment_name="+encodeURI(geid_val('comment_name'))+
          "&comment_email="+encodeURI(geid_val('comment_email'))+
          "&comment_url="+encodeURI(geid_val('comment_url'))+
          "&comment_text="+encodeURI(geid_val('comment_text'))+
          "&captcha_key="+encodeURI(geid_val('captcha_key'));
        xFn =
          function() {
            comment_show_all(mode,ID);
          }
        ajax_post(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode='+submode,'comment_new',post_vars,xFn);
      }
      return false;
    break;
    case "save":
      window.focus();
      var abort = false;
      geid('th_comment_name').style.color = 	(geid_val('comment_name')=='' ? '#ff0000' : '');
      geid('th_comment_email').style.color =	(geid_val('comment_email')=='' ? '#ff0000' : '');
      geid('th_comment_text').style.color =	(geid_val('comment_text')=='' ? '#ff0000' : '');

      if (geid_val('comment_name')=='' || geid_val('comment_email')=='' || geid_val('comment_text')=='') {
        abort=true;
      }
      if (abort){
        alert('Missing fields');
      }
      else {
        window.focus();
        post_vars =
          "comment_approved="+encodeURI(geid_val('comment_approved'))+
          "&comment_name="+encodeURI(geid_val('comment_name'))+
          "&comment_email="+encodeURI(geid_val('comment_email'))+
          "&comment_url="+encodeURI(geid_val('comment_url'))+
          "&comment_text="+encodeURI(geid_val('comment_text'));
        xFn = function() { comment_show_all(mode,ID) };
        ajax_post(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode='+submode+'&commentID='+commentID+'&rnd='+Math.random(),'comment_'+commentID,post_vars,xFn);
      }
      return false;
    break;
    case "show":
      window.focus();
      include(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode='+submode+'&commentID='+commentID+'&rnd='+Math.random(),'comment_'+commentID);
      return false;
    break;
  }
}
function comment_get_count(mode,ID) {
  include(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode=get_count&rnd='+Math.random(),'comment_count');
}
function comment_mark(mode,ID,commentID,status) {
  window.focus();
  post_vars = "comment_approved="+status;
  xFn = function() { comment_get_count(mode,ID) };
  ajax_post(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode=mark&commentID='+commentID+'&rnd='+Math.random(),'comment_'+commentID,post_vars,xFn);
  return false;
}
function comment_delete(mode,ID,commentID) {
  window.focus();
  xFn = function() { comment_get_count(mode,ID) };
  include(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode=delete&commentID='+commentID,'comment_'+commentID,xFn);
  obj = geid('comment_'+commentID);
  obj.parentNode.removeChild(obj);
}
function comment_show_all(mode,ID) {
  include(base_url+'?command=comment&mode='+mode+'&ID='+ID+'&submode=show_all','comments_list')
}
function date_selector_draw(base_id,date){
  var out = [], i, i_str;

  out.push(
     "<select class='formField' id='"+base_id+"_yyyy' onchange=\"date_selector_onchange('"+base_id+"')\">\n"
    +"  <option value=\"\"" + (date.length<4 ? " selected='selected'" : "") + ">----</option>\n"
  );

  for (i=_global_date_range_min.substr(0,4); i <= _global_date_range_max.substr(0,4); i++){
    out.push("  <option value=\""+i+"\"" + (date.length>=4 && date.substr(0,4)==i.toString() ? " selected='selected'" : "") + ">"+i+"</option>\n");
  }
  out.push("</select> - ");
  
  out.push(
     "<select class='formField' id='"+base_id+"_mm' onchange=\"date_selector_onchange('"+base_id+"')\">\n"
    +"  <option value=\"\"" + (date.length<7 ? " selected='selected'" : "") + ">--</option>\n"
  );

  for (i=1; i<=12; i++){
    i_str = lead_zero(i.toString(),2);
    out.push("  <option value=\""+i_str+"\"" + (date.length>=5 && date.substr(5,2)==i_str ? " selected='selected'" : "") + ">"+i_str+"</option>\n");
  }
  out.push("</select> - ");
  out.push(
     "<select class='formField' id='"+base_id+"_dd'>\n"
    +"  <option value=\"\"" + (date.length<10 ? " selected='selected'" : "") + ">--</option>\n"
  );

  for (i=1; i<=31; i++){
    i_str = lead_zero(i.toString(),2);
    out.push("  <option value=\""+i_str+"\"" + (date.length>=10 && date.substr(8,2)==i_str ? " selected='selected'" : "") + ">"+i_str+"</option>\n");
  }
  out.push("</select>");
  return (out.join(''));
}

function date_selector_onchange(base_id) {
  var opt, yyyy, dd, leap, i;
  if (geid_val(base_id+'_yyyy')==''){
    geid_set(base_id+'_mm','');
  }
  if (geid_val(base_id+'_mm')==''){
    geid_set(base_id+'_dd','');
  }
  else {
    yyyy = parseFloat(geid_val(base_id+'_yyyy'));
    leap = ((yyyy%4==0) && (yyyy%100!=0)) || (yyyy%400==0);

    switch (parseFloat(geid_val(base_id+'_mm'))){
      case 4: case 6: case 9: case 11:
        max_dd = 30;
      break;
      case 2:
        max_dd = (leap ? 29 : 28);
      break;
      default:
        max_dd = 31;
      break
    }

    dd = geid_val(base_id+"_dd");

    for (i=0; i< geid(base_id+'_dd').length; i++) {
      geid(base_id+'_dd').remove(i);
    }

    opt = new Option();
    opt.text = '--';
    opt.value = '';
    if (dd=='') {
      opt.selected = true;
    }
    geid(base_id+'_dd').options[0] = opt;

    for (i=1; i<=max_dd; i++) {
      i_str = lead_zero(i.toString(),2);
      opt = new Option();
      opt.text = i_str;
      opt.value = i_str;
      if (dd == i_str){
        opt.selected = true;
      }
      geid(base_id+'_dd').options[i] = opt;
    }
    if (parseFloat(dd)>max_dd){
      geid(base_id+"_dd").options[geid(base_id+"_dd").length-1].selected=true;
    }
  }
  geid(base_id+'_mm').disabled = (geid_val(base_id+'_yyyy')=='' ? true : false);
  geid(base_id+'_dd').disabled = (geid_val(base_id+'_mm')=='' ? true : false);

}


// ************************************
// * Document Reader functions        *
// ************************************
function document_reader(div) {
  var out = [], page, pages, link_title_lbl_this_prefix;
  pages = doc.pages_total;
  out.push(
     "<div style='margin:0 auto;' class='txt_c'>"
    +"  <div style='margin:0 auto;width:160px;height:30px;' class='txt_c clr_b'>\n"
    +"    <div id='mag_1' class='fl' style='margin:5px;width:15px;background-color:#c0c0c0;display:inline;font-weight:bold'></div>\n"
    +"    <div id='mag_2' class='fl' style='margin:5px;width:100px;background-color:#c0c0c0;font-weight:bold'></div>\n"
    +"    <div id='mag_3' class='fl' style='margin:5px;width:15px;background-color:#c0c0c0;font-weight:bold'></div>\n"
    +"  </div>"
    +"  <div class='clr_b'></div>"
    +"[ ");

  for (var i=0; i<pages; i++) {
    page = document_reader_get_page_name(i,pages);
    link_title_prefix = document_reader_get_page_prefix(i);
    out.push(
       "<a href='#' title='View "+link_title_prefix+page+"' onclick='return document_reader_goto_page("+i+")'>"
      +"<span id='p"+(i)+"'>"+page+"</span>"
      +"</a> ");
  }
  out.push(" ]</div>");
  out.push("<p class=\"txt_c\"><img id=\"img_doc\" border=\"1\" alt=\"\" src=\""+(doc.cover_file)+"\" /></p>");
  geid(div).innerHTML = out.join('');
  document_reader_goto_page(0,pages);
}

function document_reader_get_page_name(page){
  if (typeof(doc.named_pages[page+1])!='undefined'){
    return doc.named_pages[page+1];
  }
  if (typeof(doc.named_pages[-1*(doc.pages_total-page)])!='undefined'){
    return doc.named_pages[-1*(doc.pages_total-page)];
  }
  if (page<0 || page>doc.pages_total) {
    return "&nbsp;"
  }
  if (doc.pages_per_image==1) {
    return (page+1-doc.number_offset);
  }
  var start = ((page - 1 )*doc.pages_per_image)+ doc.number_offset;
  var end =   start+doc.pages_per_image-1;
  return start+"-"+end;
}
function document_reader_get_page_prefix(page){
  if (typeof(doc.named_pages[page+1])!='undefined'){
    return "";
  }
  if (typeof(doc.named_pages[-1*(doc.pages_total-page)])!='undefined'){
    return "";
  }
  if (page<0 || page>doc.pages_total) {
    return ""
  }
  if (doc.pages_per_image==1) {
    return "Page ";
  }
  return "Pages ";
}


function document_reader_goto_page(page) {
  var lbl_back, lbl_back_prefixed, lbl_this, lbl_next, lbl_next_prefixed, link_back, link_next;
  var m_1 = geid('mag_1');
  var m_2 = geid('mag_2');
  var m_3 = geid('mag_3');

  lbl_back =          document_reader_get_page_name(page-1);
  lbl_back_prefixed = document_reader_get_page_prefix(page-1)+lbl_back;
  link_back =	     "<a href='#' title='View "+lbl_back_prefixed+"' onclick='return document_reader_goto_page("+(page-1)+")'>&lt;</a>";

  lbl_next =          document_reader_get_page_name(page+1);
  lbl_next_prefixed = document_reader_get_page_prefix(page+1)+lbl_next;
  link_next =        "<a href='#' title='View "+lbl_next_prefixed+"' onclick='return document_reader_goto_page("+(page+1)+")'>&gt;</a>";

  m_1.innerHTML = (page==0 ? '&nbsp;' : link_back);
  m_2.innerHTML = document_reader_get_page_name(page);
  m_3.innerHTML = (page==doc.pages_total-1 ? '&nbsp;' : link_next);

  for (var i=0; i<doc.pages_total; i++){
    geid('p'+(i)).style.backgroundColor='#ffffff';
  }
  geid('p'+(page)).style.backgroundColor='#ffff00';
  geid('img_doc').src = (page==0 ? doc.cover_file : doc.pages_filepath+(page+1)+doc.pages_filetype);
  return false;
}


// ************************************
// * open_item()                      *
// ************************************
function open_item(type,ID,page) {
  switch (type) {
    case 'article':
    case 'event':
    case 'news':
    case 'job':
    case 'podcast':
      popWin(
        base_url
        +(use_friendly_urls ? type+'/'+ID : '?mode='+type+'&ID='+ID),
        type+'_'+ID,'location=1,status=1,scrollbars=1,resizable=1',720,400,1
      );
    break;
    case 'page':
      popWin(
        base_url
        +(use_friendly_urls ? page : '?page='+page),
        type+'_'+ID,'location=1,status=1,scrollbars=1,resizable=1',720,400,1
      );
    break;
    default:
      alert("open_item() - unknown type '"+type+"'");
    break;
  }
}

// ************************************
// * Polling functions                *
// ************************************
function poll(mode,ID) {
  var pw =
     "<img class='fl' src='"+base_url+"img/?mode=sysimg&img=progress_indicator.gif' width='16' height='16' alt='Please wait...'>"
    +"<div class='fl' style='color:#808080'><em>&nbsp;Loading... Please Wait</em></div><div class='clr_b'></div>";
  switch (mode){
    case "result":
      geid('poll_'+ID).innerHTML=pw;
      include(base_url+'?command=poll_result&targetID='+ID,'poll_'+ID);
      return false;
    break;
    case "show":
      geid('poll_'+ID).innerHTML=pw;
      include(base_url+'?command=poll_show&targetID='+ID,'poll_'+ID);
      return false;
    break;
    case "vote":
      var a=geid_val('poll_answer_'+ID);
      if (a===false) {
        alert('Please choose an option');
        return false;
      }
      geid('poll_'+ID).innerHTML=pw;
      include(base_url+'?command=poll_vote&targetID='+ID+'&targetValue='+a,'poll_'+ID);
      return false;
    break;
  }
}


// ************************************
// * Popup Layer functions            *
// ************************************
/**
 * POPUP WINDOW CODE v1.1
 * By Seth Banks (webmaster at subimage dot com)
 * http://www.subimage.com/
 *
 * Contributions by Eric Angel (tab index code) and Scott (hiding/showing selects for IE users)
 * Up to date code can be found at http://www.subimage.com/dhtml/subModal
 * This code is free for you to use anywhere, just keep this comment block.
 */

// Popup code
var gPopupMask = null;
var gPopupContainer = null;
var gPopFrame = null;
var gReturnFunc;
var gPopupIsShown = false;
var gFckEditorsLoading = new Array();

var gHideSelects = false;


var gTabIndexes = new Array();
// Pre-defined list of tags we want to disable/enable tabbing into
var gTabbableTags = new Array("A","BUTTON","TEXTAREA","INPUT","IFRAME");

// If using Mozilla or Firefox, use Tab-key trap.
if (!document.all) {
	document.onkeypress = keyDownHandler;
}

/**
 * Initializes popup code on load.
 */

/**
 * @argument width - int in pixels
 * @argument height - int in pixels
 * @argument returnFunc - function to call when returning true from the window.
 */
function showPopWin(title,body,width,height,returnFunc) {
  gPopupMask =		geid("popupMask");
  gPopupContainer =	geid("popupContainer");
  gPopFrame =		geid("popupFrame");

  // check to see if this is IE version 6 or lower. hide select boxes if so
  // maybe they'll fix this in version 7?

  var brsVersion = parseInt(window.navigator.appVersion.charAt(0), 10);
  if (brsVersion <= 6 && window.navigator.userAgent.indexOf("MSIE") > -1) {
    gHideSelects = true;
  }

  gPopupIsShown = true;
  disableTabIndexes();
  gPopupMask.style.display = "block";
  gPopupContainer.style.display = "block";

  // calculate where to place the window on screen
  centerPopWin(width, height+120);
  var titleBarHeight = parseInt(geid("popupTitleBar").offsetHeight, 10);

  gPopupContainer.style.width = width + "px";
  gPopupContainer.style.height = (height+titleBarHeight) + "px";

  geid("popupTitle").innerHTML='<strong>'+system_family+'</strong>: '+title;
  geid("popupBody").innerHTML=body;
  gReturnFunc = returnFunc;
  // for IE
  if (gHideSelects == true) {
    hideSelectBoxes();
  }
}
function setFocus(id) {
  if (!geid(id)){
    return;
  }
  var obj = geid(id);
  obj.focus(); // needs to be done twice for IE7 - don't know why
} 

//
var gi = 0;
function centerPopWin(width, height) {
  if (gPopupIsShown == true) {
    if (width == null || isNaN(width)) {
      width = gPopupContainer.offsetWidth;
    }
    if (height == null) {
      height = gPopupContainer.offsetHeight;
    }

    var fullHeight = getViewportHeight();
    var fullWidth = getViewportWidth();

    var theBody = document.documentElement;

    var scTop = parseInt(theBody.scrollTop,10);
    var scLeft = parseInt(theBody.scrollLeft,10);

    gPopupMask.style.height = fullHeight + "px";
    gPopupMask.style.width = fullWidth + "px";
    gPopupMask.style.top = scTop + "px";
    gPopupMask.style.left = scLeft + "px";

    var titleBarHeight = parseInt(geid("popupTitleBar").offsetHeight, 10);

    gPopupContainer.style.top = (scTop + ((fullHeight - (height+titleBarHeight)) / 2)) + "px";
    gPopupContainer.style.left =  (scLeft + ((fullWidth - width) / 2)) + "px";
    //alert(fullWidth + " " + width + " " + gPopupContainer.style.left);
  }
}
addEvent(window, "resize", centerPopWin);
addEvent(window, "scroll", centerPopWin);
window.onscroll = centerPopWin;

/**
 * @argument callReturnFunc - bool - determines if we call the return function specified
 * @argument returnVal - anything - return value
 */
function hidePopWin(callReturnFunc) {
  gPopupIsShown = false;
  restoreTabIndexes();
  if (gPopupMask == null) {
    return;
  }
  gPopupMask.style.display = "none";
  gPopupContainer.style.display = "none";
  if (callReturnFunc == true && gReturnFunc != null) {
    gReturnFunc(window.frames["popupFrame"].returnVal);
  }
  // display all select boxes
  if (gHideSelects == true) {
    displaySelectBoxes();
  }
}

/**
 * Sets the popup title based on the title of the html document it contains.
 * Uses a timeout to keep checking until the title is valid.
 */

// Tab key trap. iff popup is shown and key was [TAB], suppress it.
// @argument e - event - keyboard event that caused this function to be called.
function keyDownHandler(e) {
    if (gPopupIsShown && e.keyCode == 9)  return false;
    return true;
}

// For IE.  Go through predefined tags and disable tabbing into them.
function disableTabIndexes() {
  if (document.all) {
    var i = 0;
    for (var j = 0; j < gTabbableTags.length; j++) {
      var tagElements = document.getElementsByTagName(gTabbableTags[j]);
      for (var k = 0 ; k < tagElements.length; k++) {
        gTabIndexes[i] = tagElements[k].tabIndex;
        tagElements[k].tabIndex="-1";
        i++;
      }
    }
  }
}

// For IE. Restore tab-indexes.
function restoreTabIndexes() {
  if (document.all) {
    var i = 0;
    for (var j = 0; j < gTabbableTags.length; j++) {
      var tagElements = document.getElementsByTagName(gTabbableTags[j]);
      for (var k = 0 ; k < tagElements.length; k++) {
        tagElements[k].tabIndex = gTabIndexes[i];
        tagElements[k].tabEnabled = true;
        i++;
      }
    }
  }
}


/**
* Hides all drop down form select boxes on the screen so they do not appear above the mask layer.
* IE has a problem with wanted select form tags to always be the topmost z-index or layer
*
* Thanks for the code Scott!
*/
function hideSelectBoxes() {
  for(var i = 0; i < document.forms.length; i++) {
    for(var e = 0; e < document.forms[i].length; e++){
      if(document.forms[i].elements[e].tagName == "SELECT") {
        document.forms[i].elements[e].style.visibility="hidden";
      }
    }
  }
}

/**
* Makes all drop down form select boxes on the screen visible so they do not reappear after the dialog is closed.
* IE has a problem with wanted select form tags to always be the topmost z-index or layer
*/
function displaySelectBoxes() {
  for(var i = 0; i < document.forms.length; i++) {
    for(var e = 0; e < document.forms[i].length; e++){
      if(document.forms[i].elements[e].tagName == "SELECT") {
      document.forms[i].elements[e].style.visibility="visible";
      }
    }
  }
}

function popup_hide_on_loaded() {
  if (gFckEditorsLoading==0) {
    hidePopWin(null);
  }
  else {
    setTimeout('popup_hide_on_loaded()',500);
  }
}

// ************************************
// * (End of Popup Layer functions)   *
// ************************************
// These ones are mine...

// ************************************
// * Popup Dialog                     *
// ************************************
function popup_dialog(title,html,width,height,btn_ok_txt,btn_cancel_txt,btn_ok_js,focus){
  var h,response;
  h = "<div id='popup_wait' style='display:none;'>"
     +"<img class='fl' src='"+base_url+"img/?mode=sysimg&img=icon_hourglass.gif' width='32' height='32' alt='Please wait...'>"
     +"<div class='fl' id='popup_wait_txt'></div>"
     +"<div class='clr_b'></div>"
     +"</div>"
     +"<div id='popup_content'>"
     +html
     +"</div>"
     +"<div id='popup_buttons' style='padding-top:5px;margin:auto;' class='txt_c'>"
     +"<input type='button' id='btn_ok' class='formButton' style='width:60px;' value='"+btn_ok_txt+"' "
     +"onclick=\""
     +(btn_ok_js!='' ? btn_ok_js+";" : "")
     +"this.disabled=1;if(geid('btn_cancel')){geid('btn_cancel').disabled=1;};"
     +"hidePopWin(null);response=true;"
     +"\" />"
     +(btn_cancel_txt=="" ?
        ""
      : "<input type='button' id='btn_cancel' class='formButton' style='width:60px;' value='"+btn_cancel_txt+"' onclick='hidePopWin(null);response=false;' />"
      )
     +"</div>"
     ;
  showPopWin(title,h,width,height,null);
  setFocus(focus);
  return response;
}
function popup_wait(txt) {
  geid('popup_buttons').style.display='none';
  geid('popup_wait_txt').innerHTML=txt;
  geid('popup_content').style.display='none';
  geid('popup_wait').style.display='';
}

function show_popup_screensize(current,option_csv) {
  var h, j, option_arr;
  option_arr = option_csv.split(',');
  var valid = false;
  for (var i in option_arr) {
    option = option_arr[i];
    if (option==current) {
      valid=true;
    }
  }
  if (!valid) { current = option_arr[0];}

  h = "Please select your preferred screen size:"
     +"<input type='hidden' id='screen_size_old' value='"+current+"'/>"
     +"<input type='hidden' id='screen_size_new' value='"+current+"'/>"
     +"<div style='padding:5px;'>";

  for (var i in option_arr) {
    option = option_arr[i];
    h +=
      "<label>"
     +"<input type='radio' name='screen_size' value='" + option + "'"
     +(current==option ? " checked='checked'" : '')
     +" onchange=\"geid('screen_size_new').value=this.value;\"/>"
     +option
     +"</label><br/>";
  }
  h += "</div>";
  j = "if(geid_val('screen_size_old')==geid_val('screen_size_new')){"
     +"hidePopWin(null);return false;}"
     +"popup_wait('Please wait...<br/>Saving preferences');"
     +"setScreenSize(geid_val('screen_size_new'));geid('form').submit();";
  popup_dialog("Screen size",h,200,260,'OK','Cancel',j);
}

function show_popup_please_wait() {
  var html =
    "<img src='"+base_url+"img/?mode=sysimg&amp;img=icon_hourglass.gif' width='32' height='32' alt='Please wait...' align='left'>" +
    "Loading...<br/>Please wait";
  showPopWin("",html,120, 180, null);
}


function selector_csv_add(div,value){
  var selector = geid('selector_csv_'+div);
  var out_txt =  new Array();
  var out_val =  new Array();

  var val_arr = geid_val(div).split(',');
  var included = false
  for (var i in val_arr){
    if (Trim(val_arr[i])==value){
      included = true;
    }
  }
  if (!included) {
    val_arr.push(value);
    geid(div).value=val_arr.join(', ');
    selector_csv_delete(div,''); // Clear null value if present
  }
  else {
    ToolTips.out();ToolTips.attachBehavior();
  }
  selector.selectedIndex=0;
}

function selector_csv_delete(div,value){
  var selector = geid('selector_csv_'+div);
  var out_txt =  new Array();
  var out_val =  new Array();

  var input_arr = geid_val(div).split(',');
  for (var i in input_arr){
    if (Trim(input_arr[i])!=value){
      for (var j=0; j<selector.options.length; j++){
        if (Trim(input_arr[i])==selector.options[j].value){
          out_val[out_val.length] = selector.options[j].value;
        }
      }
    }
  }
  geid(div).value=out_val.join(', ');
  selector_csv_show(div)
  ToolTips.out();ToolTips.attachBehavior();
}
function selector_csv_show(div){
  var selector = geid('selector_csv_'+div);
  var out_txt =  new Array();
  var out_val =  new Array();
  var bgcolorClass, label, tooltip, value;
 
  var input_arr = geid_val(div).replace(/ ,/g,',').split(',');
  for (var i in input_arr){
    for (var j=0; j<selector.options.length; j++){
      if (Trim(input_arr[i]).toUpperCase()==selector.options[j].value.toUpperCase()){
        bgcolorClass = selector.options[j].className;
        label =        selector.options[j].text;
        tooltip =      (label.substr(0,2)=='* ' ? label.substr(2) : label);
        tooltip =      (tooltip.substr(tooltip.length-1)==')' ? tooltip.substr(0,tooltip.indexOf('(')) : tooltip);
        value =        selector.options[j].value;
        out_txt[out_txt.length] =
           "<a class=\""+bgcolorClass+"\" title=\""
          +(value ?
               "Click to remove "
              +"'<b>"+tooltip+"</b>' from this list<br />or choose more options from the dropdown list"
            : "Choose entries from the dropdown list"
           )
          +"\" href=\"javascript:selector_csv_delete('"+div+"','"
          +value+"')\">"
          +label+"</a>"
      }
    }
  }
  geid('selector_csv_div_'+div).innerHTML=out_txt.join(', ');
}



// ************************************
// * Text Resizer functions           *
// ************************************
function cssAttributeGet(selectorText,attribute) {
  var styleSheet, rules, i, ii;
  selectorText=selectorText.toLowerCase();
  if (!document.styleSheets) {
    return false;
  }
  for (i=0; i<document.styleSheets.length; i++) {
    styleSheet=document.styleSheets[i];
    rules = (styleSheet.cssRules ? styleSheet.cssRules : styleSheet.rules);
    for (ii=0; ii<rules.length; ii++) {
      if (
        rules[ii] && rules[ii].selectorText &&
        rules[ii].selectorText.toLowerCase()==selectorText &&
        rules[ii].style[attribute]
      ){
        return (rules[ii].style[attribute]);
      }
    }
  }
  return false;
}
function cssAttributeSet(selectorText,attribute,value) {
  var styleSheet, rules, i, ii;
  selectorText=selectorText.toLowerCase();
  if (!document.styleSheets) {
    return false;
  }
  for (i=0; i<document.styleSheets.length; i++) {
    styleSheet=document.styleSheets[i];
    rules = (styleSheet.cssRules ? styleSheet.cssRules : styleSheet.rules);
    for (ii=0; ii<rules.length; ii++) {
      if (
        rules[ii] && rules[ii].selectorText &&
        rules[ii].selectorText.toLowerCase()==selectorText
      ){
        rules[ii].style[attribute]=value;
        return true;
      }
    }
  }
  return false;
}

function setTextSize(size){
  var expdate = new Date();
  expdate.setTime(expdate.getTime() + (1000*3600*24*365));
  document.cookie = 'textsize=' + size + '; expires=' + expdate.toGMTString();
  var font_scale = (cur_size=='80%' ? '120' : '80');
  if (!cssAttributeSet('.zoom_text','fontSize',font_scale+'%')){
    self.location.reload();
  }
}
function setScreenSize(size){
  var expdate = new Date();
  expdate.setTime(expdate.getTime() + (1000*3600*24*365));
  document.cookie = 'screensize=' + size + '; expires=' + expdate.toGMTString();
}

function toggleTextSize() {
  var cur_size = cssAttributeGet('.zoom_text','fontSize');
  var expdate = new Date();
  expdate.setTime(expdate.getTime() + (1000*3600*24*365));
  document.cookie = 'textsize=' + (cur_size=='80%' ? 'big' : 'small') + '; expires=' + expdate.toGMTString();
  setDisplay('text_sizer_reduce',cur_size=='80%');
  setDisplay('text_sizer_enlarge',cur_size=='120%');

  var font_scale = (cur_size=='80%' ? '120' : '80');
  if (!cssAttributeSet('.zoom_text','fontSize',font_scale+'%')){
    self.location.reload();
  }
}

// ************************************
// * Static Tooltips                  *
// ************************************
/**
 * General Horde UI effects javascript.
 * $Horde: horde/js/horde.js,v 1.14.2.5 2006/05/25 18:07:26 slusarz Exp $
 * Changes by Martin Francis in 1.0.36 (2007-07-24) to initialise variables with var keyword
 * See http://www.fsf.org/copyleft/lgpl.html for LGPL licencing
 */

var ToolTips = {
  CURRENT: null,
  TIMEOUT: null,
  LINK: null,
  attachBehavior: null,
  over: null,
  out: null,
  show: null
}

function initialise_tooltips() {
  ToolTips.attachBehavior = function(){
    links = document.getElementsByTagName('a');
    for (i = 0; i < links.length; i++) {
      if (links[i].title) {
        links[i].setAttribute('nicetitle', links[i].title);
        links[i].removeAttribute('title');
        addEvent(links[i], 'mouseover', ToolTips.over);
        addEvent(links[i], 'mouseout', ToolTips.out);
        addEvent(links[i], 'focus', ToolTips.over);
        addEvent(links[i], 'blur', ToolTips.out);
      }
    }
  }
  ToolTips.over = function(e){
    if (typeof ToolTips == 'undefined') {
      return;
    }
    if (ToolTips.TIMEOUT) {
      window.clearTimeout(ToolTips.TIMEOUT);
    }
    if (window.event && window.event.srcElement) {
      ToolTips.LINK = window.event.srcElement;
    } else if (e && e.target) {
      ToolTips.LINK = e.target;
    }
    ToolTips.TIMEOUT = window.setTimeout('ToolTips.show()', 300)
  }
  ToolTips.out = function() {
    if (typeof ToolTips == 'undefined') {
      return;
    }
    if (ToolTips.TIMEOUT) {
      window.clearTimeout(ToolTips.TIMEOUT);
    }
    if (ToolTips.CURRENT) {
      document.getElementsByTagName('body')[0].removeChild(ToolTips.CURRENT);
      ToolTips.CURRENT = null;
      var iframe = geid('iframe_tt');
      if (iframe != null) {
        iframe.style.display = 'none';
      }
    }
  }
  ToolTips.show = function() {
    var link, nicetitle, d, i, STD_WIDTH, MAX_WIDTH, nicetitle_length, lines, w, mpos;
    var h_pixels, t_pixels, mpos, mx, my, left;
    if (typeof ToolTips == 'undefined' || !ToolTips.LINK) {
      return;
    }
    if (ToolTips.CURRENT) {
      ToolTips.out();
    }
    link = ToolTips.LINK;
    while (!link.getAttribute('nicetitle') && link.nodeName.toLowerCase() != 'body') {
      link = link.parentNode;
    }
    nicetitle = link.getAttribute('nicetitle');
    if (!nicetitle) {
      return;
    }
    nicetitle = nicetitle.replace(/ /g,"&nbsp;").replace(/\[b\]/g,"<b>").replace(/\[\/b\]/g,"</b>").replace(/\\n/g,"<br />");
    d = document.createElement('div');
    d.className = 'nicetitle';
    d.innerHTML = nicetitle;
    STD_WIDTH = 100;
    MAX_WIDTH = 600;
    if (window.innerWidth) {
      MAX_WIDTH = Math.min(MAX_WIDTH, window.innerWidth - 20);
    }
    if (document.body && document.body.scrollWidth) {
      MAX_WIDTH = Math.min(MAX_WIDTH, document.body.scrollWidth - 20);
    }
    nicetitle_length = 0;
    
    lines = nicetitle.replace(/<br ?\/>/g, "\n").split("\n");
    for (i = 0; i < lines.length; i++) {
      nicetitle_length = Math.max(nicetitle_length, lines[i].length);
    }
    h_pixels = nicetitle_length * 6.5;
    t_pixels = nicetitle_length * 6.5;
    if (h_pixels > STD_WIDTH) {
      w = h_pixels;
    } else if (STD_WIDTH > t_pixels) {
      w = t_pixels;
    } else {
      w = STD_WIDTH;
    }

    mpos = obj_getCoords(link);
    mx = mpos['left'];
    my = mpos['top'];

    left = mx + 20;
    if (window.innerWidth && ((left + w) > window.innerWidth)) {
      left = window.innerWidth - w - 40;
    }
    if (document.body && document.body.scrollWidth && ((left + w) > document.body.scrollWidth)) {
      left = document.body.scrollWidth - w - 25;
    }
    d.id = 'toolTip';
    d.style.left = Math.max(left, 5) + 'px';
    d.style.width = Math.min(w, MAX_WIDTH) + 'px';
    d.style.top = (my + 25) + 'px';
    d.style.display = "block";
    try {
      document.getElementsByTagName('body')[0].appendChild(d);
      ToolTips.CURRENT = d;

      if (typeof ToolTips_Option_Windowed_Controls != 'undefined') {
        var iframe = geid('iframe_tt');
        if (iframe == null) {
          iframe = document.createElement(
            "<iframe src='javascript:false;' name='iframe_tt' id='iframe_tt' scrolling='no' frameborder='0' style='position:absolute; top:0px; left:0px; display:none;'></iframe>"
          );
          document.getElementsByTagName('body')[0].appendChild(iframe);
        }
        iframe.style.width = d.offsetWidth;
        iframe.style.height = d.offsetHeight;
        iframe.style.top = d.style.top;
        iframe.style.left = d.style.left;
        iframe.style.position = "absolute";
        iframe.style.display = "block";
        d.style.zIndex = 100;
        iframe.style.zIndex = 99;
      }
    }
    catch (e) {
    }
  }
};

var EventCache = function(){
  var listEvents = [];
  return {
    listEvents: listEvents,
    add: function(node, sEventName, fHandler, bCapture) {
      listEvents.push(arguments);
    },
    flush: function() {
      var i, item;
      for (i = listEvents.length - 1; i >= 0; i = i - 1) {
        item = listEvents[i];
        if (item[0].removeEventListener) {
          item[0].removeEventListener(item[1], item[2], item[3]);
        };
        /* From this point on we need the event names to be
         * prefixed with 'on'. */
        if (item[1].substring(0, 2) != 'on') {
          item[1] = 'on' + item[1];
        }
        if (item[0].detachEvent) {
          item[0].detachEvent(item[1], item[2]);
        }
        item[0][item[1]] = null;
      }
    }
  };
}();

/**
 * end of General Horde UI effects javascript.
 * See http://www.fsf.org/copyleft/lgpl.html for LGPL licencing
 */

// ************************************
// * Navsuite code                    *
// ************************************
// Fired on navbar button mouseover
function img_state(img,state) {
  var obj =	geid('btn_'+img);
  var h =	obj.height;
  var pos_arr =	obj.style.backgroundPosition.split(' ');
  var new_pos = ""
  switch (state) {
    case 'a':
      new_pos = 0;
    break;
    case 'd':
      new_pos = -1*h;
    break;
    case 'n':
      new_pos = -2*h;
    break;
    case 'o':
      new_pos = -3*h;
    break;
  }
  obj.style.backgroundPosition = pos_arr[0]+' '+new_pos+'px'
  return true;
}

function add_btn(ID,parentID) {
  var obj = geid("nav_link_"+ID);
  if (obj) {  // invisible buttons may still be cached - don't try to link to them
    addEvent(obj, 'mousedown', function(e){ return img_state(ID,'d');});
    if (parentID==1) {
      addEvent(obj, 'mouseover', function(e){return img_state(ID,'o');});
      addEvent(obj, 'mouseout',  function(e){_CM_type='';return img_state(ID,(global_active_btns.toString().indexOf(ID)!==-1 ? 'a' :'n'));});
    }
    else {
      addEvent(obj, 'mouseover', function(e){return img_state(ID,'o');});
      addEvent(obj, 'mouseout',  function(e){_CM_type='';return img_state(ID,(global_active_btns.toString().indexOf(ID)!==-1 ? 'a' :'n'));});
    }
  }
}

// Called for IE only to initialise events for mouseover list items
function dropdownMenu(theMenu) {
  if (document.all && document.getElementById) {
    navRoot = geid(theMenu);
    if (!navRoot) {
      return;
    }
    for (var i=0; i<navRoot.childNodes.length; i++) {
      node = navRoot.childNodes[i];
      if (node.nodeName=='LI') {
        node.onmouseover=function() {
          this.className+=' over';
          this.style.zIndex=2;
        }
        node.onmouseout=function() {
          this.className=this.className.replace(' over', '');
          this.style.zIndex=1;
        }

        for (var j=0; j<node.childNodes.length; j++) {
          subnode = node.childNodes[j];
          if (subnode.nodeName=='UL') {
            subnode.onmouseover=function() {
              this.parentNode.style.zIndex=2;
              this.style.zIndex=2;
            }
            subnode.onmouseout=function() {
              this.parentNode.style.zIndex=1;
              this.style.zIndex=1;
            }

            for (var k=0; k<subnode.childNodes.length; k++) {
              subsubnode = subnode.childNodes[k];
              if (subsubnode.nodeName=='LI') {
                subsubnode.onmouseover=function() {
                  this.className+=' over';
                  this.parentNode.style.zIndex=2;
                  this.style.zIndex=2;
                }
                subsubnode.onmouseout=function() {
                  this.className=this.className.replace(' over', '');
                  this.parentNode.style.zIndex=1;
                  this.style.zIndex=1;
                }
              }
            }

          }
        }
      }
    }
  }
}

// ************************************
// * Calendar Functions:              *
// ************************************
function cal_goto(int_val) {
  var obj_mm, obj_yyyy, M;
  obj_form =	geid('form');
  obj_mm =	geid('MM');
  obj_yyyy =	geid('YYYY');
  var M =	parseFloat(obj_mm.value);
  switch(int_val) {
    case -120:
      obj_yyyy.value = parseInt(obj_yyyy.value)-10;
    break;
    case -12:
      obj_yyyy.value = parseInt(obj_yyyy.value)-1;
    break;
    case -1:
      M=M-1;
      if (M < 1) {
        M = 12;
        obj_yyyy.value = parseInt(obj_yyyy.value)-1;
      }
    break;
    case 1:
      M=M+1;
      if (M > 12) {
        M = 1;
        obj_yyyy.value = parseInt(obj_yyyy.value)+1;
      }
    break;
    case 12:
      obj_yyyy.value = parseInt(obj_yyyy.value)+1;
    break;
    case 120:
      obj_yyyy.value = parseInt(obj_yyyy.value)+10;
    break;
  }
  obj_mm.value = (M.length==1 ? "0"+M : ""+M);
  obj_form.submit();
}

function cal_picker(field) {
  var DD, MM, YY, YYYYMMDD;
  YYYYMMDD = geid(field).value;
  YYYY = YYYYMMDD.substr(0,4);
  MM = YYYYMMDD.substr(5,2);
  DD = YYYYMMDD.substr(8,2);
  popWin(
    base_url+'?mode=cal_popup&field='+field+
      (YYYY!='' ? '&YYYY='+YYYY : '')+
      (MM!='' ? '&MM='+MM : '')+
      (DD!='' ? '&DD='+DD : ''),
    'popCalPicker','scrollbars=0,resizable=1,status=1',220,158,'centre');
}

function ajax_config_display(result, div) {
  var assoc = [],out = [],checksum_final = '',i;
  for(i = 1; i <= result[0]; i++) {
    if (result[i]['category']=='config') {
      assoc[result[i]['title']] = result[i]['content'];
    }
    if (result[i]['category']=='checksum' && result[i]['title']=='checksum_final') {
      checksum_final = result[i]['content'];
    }
  }
  if (assoc['db_cstarget']==checksum_final) {
    assoc['db_cstarget'] = "<span style='color:#008000'><b>" + checksum_final + "</b></span>";
  }
  else {
    assoc['db_cstarget'] = "<span style='color:#FF0000'><b>" + checksum_final + "</b></span> (expected " + assoc['db_cstarget'] + ")";
  }
  if (assoc['checksum_status']=='Pass') {
    assoc['checksum_status'] = "<span style='color:#008000'><b>" + assoc['checksum_status'] + "</b></span>";
  }
  else {
    assoc['checksum_status'] = "<span style='color:#FF0000'><b>" + assoc['checksum_status'] + "</b></span>";
  }
  if (assoc['google_key_status']=='Pass') {
    assoc['google_key_status'] = "<span style='color:#008000'><b>" +  assoc['google_key_status'] + "</b></span>";
  }
  else {
    assoc['google_key_status'] = "<span style='color:#FF0000'><b>" + assoc['google_key_status'] + "</b></span>";
  }
  assoc['build_version'] = "<a href=\"javascript:void version('"+assoc['build_version']+"')\"><b>"+assoc['build_version']+"</b></a>";
  assoc['URL'] = "<a href=\"javascript:void popWin('"+assoc['URL']+"','"+assoc['URL'].replace(/[.\/\:]+/g,'_')+"','scrollbars=1,resizable=1,status=0',800,600,'centre');\"><b>"+assoc['URL']+"</b></a>";
  out.push("<table cellpadding='2' cellspacing='0' class='report'>");
  for (i=0; i < config_rows.length; i++) {
    out.push("<tr>");
    out.push("<td class='nowrap' style='border-left: none"+(config_rows[i]=='URL' ? ';background-color: #e8e8e8;' : '')+"'>");
    out.push((typeof(assoc[config_rows[i]])!='undefined' && assoc[config_rows[i]]!='' ? assoc[config_rows[i]] : '&nbsp;'));
    out.push("</td></tr>");
  }
  out.push("</table>\n");
  geid(div).innerHTML = out.join('');
}

function ajax_div_loading(obj,msg) {
  var c = obj_getCoords(obj);

  var div1 = obj.appendChild(document.createElement("div"));
  var div2 = obj.appendChild(document.createElement("div"));
  var ds1 = div1.style;
  var ds2 = div2.style;

  ds1.backgroundColor = "#aaaaaa";
  ds1.zIndex = 998;
  ds1.opacity = "0.6";
  ds1.filter = "alpha(opacity=60)";
  ds1.top = c['top'];
  ds1.left = c['left'];
  ds1.height = obj.offsetHeight;
  ds1.width = parseFloat(obj.offsetWidth)+20+"px";
  ds1.position = "absolute";

  ds2.backgroundColor = "#f0f0ff";
  ds2.color = "#404060";
  ds2.zIndex = 999;
  ds2.opacity = "0.95";
  ds2.filter = "alpha(opacity=95)";
  ds2.top = parseFloat(c['top'])+10+"px";
  ds2.left = parseFloat(c['left'])+10+"px";
  ds2.lineHeight = "40px";
  ds2.width = obj.offsetWidth;
  ds2.position = "absolute";
  ds2.textAlign = "center";
  ds2.fontSize = "14pt";
  ds2.border = "solid 1px #8080a0";
  div2.innerHTML = msg;
}

function ajax_keytest(e) {
  if(!e) {
    e=window.event;
  }
  keys_arr = new Array(9,37,38,39,40);
  for (var i=0; i<keys_arr.length; i++) {
    if (e.keyCode==keys_arr[i]) {
      return false;
    }
  }
  return true;
}

function ajax_post(xUrl,xId,xParams,xFn) {
  if (ajax_controls[xId]) {
    ajax_controls[xId].abort();
    delete ajax_controls[xId];
  }
  var xmlhttp = false;

  /*@cc_on @*/
  /*@if (@_jscript_version >= 5)
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  }
  catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
      xmlhttp = false;
    }
  }
  @end @*/
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
    xmlhttp = new XMLHttpRequest();
  }
  xmlhttp.open("POST",xUrl,true);
  xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState==4) {
      delete ajax_controls[xId];
      if (xFn) {
        xFn(xmlhttp.responseText);
      }
      if (geid(xId)) {
        geid(xId).innerHTML = xmlhttp.responseText;
      }
    }
  }
  ajax_controls[xId]=xmlhttp;
  xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xmlhttp.setRequestHeader("Content-length", xParams.length);
  xmlhttp.setRequestHeader("Connection", "close");
  xmlhttp.send(xParams)
}


function ajax_report(reportID,report_name,toolbar) {
  var pw =
     "<img src='"+base_url+"img/?mode=sysimg&img=progress_indicator.gif' width='16' height='16' alt='Please wait...'>"
    +"&nbsp; <strong>"+system_family+" loading...</strong>";
  ajax_div_loading(geid('report_'+reportID),pw);
  xFn =
    function() {
      externalLinks();
      if (window.CM_load) { CM_load(); }
    }

  ajax_post(
    base_url+'?command=report',
    'report_'+encodeURI(reportID),
     'report_name='+encodeURI(report_name)
    +'&toolbar='+encodeURI(toolbar)
    +'&sortBy='+encodeURI(geid_val('sortBy'))
    +'&limit='+encodeURI(geid_val('limit'))
    +'&offset='+encodeURI(geid_val('offset'))
    +'&filterField='+encodeURI(geid_val('filterField'))
    +'&filterExact='+encodeURI(geid_val('filterExact'))
    +'&filterValue='+encodeURI(geid_val('filterValue'))
    +'&offset='+encodeURI(geid_val('offset'))
    +'&submode='+encodeURI(geid_val('submode'))
    +'&selectID='+encodeURI(geid_val('selectID'))
    +'&targetReportID='+encodeURI(geid_val('targetReportID'),
     xFn
    )
  );
}

function column_over(obj_cell,int_state) {
  switch (int_state) {
    case 'n': obj_cell.className = 'grid_head_n'; break;
    case 'o': obj_cell.className = 'grid_head_o'; break;
    case 'd': obj_cell.className = 'grid_head_d'; break;
  }
  return true;
}


function combo_selector_set(field_name,width){
  var val, obj_field, obj_field_alt, obj_field_sel, field_alt_span;

  obj_field =          geid(field_name);
  obj_field_alt =      geid(field_name+'_alt');
  obj_field_sel =      geid(field_name+'_selector');
  field_alt_span = field_name+'_alt_span';

  val = obj_field_sel.options[obj_field_sel.selectedIndex].value;

  if (val=='--') {
    setDisplay(field_alt_span,1);
    if (width) {
      obj_field_sel.style.width=(parseInt(width)/2)+'px';
    }
    obj_field.value=obj_field_alt.value;
  }
  else {
    setDisplay(field_alt_span,0);
    if (obj_field_sel && obj_field_sel.style && obj_field_sel.style.width && width) {
      obj_field_sel.style.width=(parseInt(width)+4)+'px';
    }
    obj_field.value=val;
    obj_field_alt.value = '';
  }
  if (val=='') {
    obj_field_sel.selectedIndex=0;
  }
  return obj_field.value;
}

function donate(key) {
  geid('command').value='donate';
  geid('form').target='_blank';
  geid('targetValue').value=key;
  geid('form').submit();
  geid('command').value='';
  geid('targetValue').value='';
  geid('form').target='';
}
function get_valid_name(name) {
  if (isNaN(name.substr(0,1))) {
    return name;
  }
  return valid_prefix+name;
}

function goto_page(what) {
  geid('goto').value=what;
  geid('mode').value='';
  geid('form').submit();
}

function img_over(obj,baseimg,state) {
  var src = "";
  switch (baseimg) {
    case "link":
      src = base_url+'img/?mode=sysimg&img=txt_link_'+(state ? 'o' : 'n')+'.gif';
    break;
    case "map":
      src = base_url+'img/?mode=sysimg&img=txt_map_'+(state ? 'o' : 'n')+'.gif';
    break;
    case "read_more":
      src = base_url+'img/?mode=sysimg&img=txt_read_more_'+(state ? 'o' : 'n')+'.gif';
    break;
    default:
      src = base_url+'img/?mode=sysimg&img='+baseimg+'_'+(state ? 'o' : 'n')+'.gif';
    break;     
  }
  obj.src = src;
  return true;
}

function include(xUrl,xId,xFn) {
  // http://jmaguire.com/downloads/source_code/javascript/client_side_include/
  // Used by Daily Bible Verse
  if (typeof(ajax_controls[xId]) != 'undefined') {
    xmlhttp.abort();
    delete ajax_controls[xId];
  }
  var xmlhttp = false;
  /*@cc_on @*/
  /*@if (@_jscript_version >= 5)
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  }
  catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
      xmlhttp = false;
    }
  }
  @end @*/
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
    xmlhttp = new XMLHttpRequest();
  }
  xmlhttp.open("GET", xUrl,true);
  xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState==4) {
      delete ajax_controls[xId];
      if (geid(xId)) {
        geid(xId).innerHTML = xmlhttp.responseText;
      }
      if (xFn) {
        xFn();
      }
    }
  }
  ajax_controls[xId]=xmlhttp;
  xmlhttp.send(null)
}

function makeReadOnly(id) {
  geid(id).style.backgroundColor='#f0f0f0';
  geid(id).style.color='#404040';
  geid(id).attachEvent(
    "onfocus",
    function(){
      geid(id).blur();
    }
  );
}


// ************************************
// * nav_mouse()                      *
// ************************************
// simplifies nav rollovers for trees:
function nav_mouse(div,state,parentDiv){
  switch (state) {
    case "o":
      img_state(div,'o');
      if (parent!=null) {
        img_state(parentDiv,'o');
      }
    break;
    case "n":
      img_state(div,'n');
      if (parent!=null) {
        img_state(parentDiv,'n');
      }
    break;
  }
  return true;
}

function obj_getCoords(obj) {
  var xp, yp, op;
  xp = obj.offsetLeft;	// Element's offset x in pixels
  yp = obj.offsetTop;	// Element's offset y in pixels
  // Now loop through all parent containers, adding offsets as we do so
  while (obj.offsetParent) {
    op = obj.offsetParent;	// Get container parent
    xp = xp + op.offsetLeft;	// Add this element's offset x in pixels
    yp = yp + op.offsetTop;		// Add this element's offset y in pixels
    obj = obj.offsetParent;	// Update current container
  }
  return {'left': xp, 'top': yp};
}

function pad(text,spaces) {
  if (text.length>=spaces) {
    return text;
  }
  var padstr = '                 ';
  return text+padstr.substr(0,spaces-text.length);
}
function lead_zero(text,digits) {
  if (text.length>=digits) {
    return text;
  }
  var leadstr = '0000000000000000';
  return leadstr.substr(0,digits-text.length)+text;
}

// ************************************
// * popWin()                         *
// ************************************
function popWin(theURL,winName,features,windowx,windowy,centre) {
  if (centre == "centre") {
	var availx;
	var availy;
    var posx;
    var posy;
	availx = screen.availWidth;
	availy = screen.availHeight;
    posx = (availx - windowx)/2;
    posy = (availy - windowy)/2;
    var theWin = window.open(theURL,winName,features+',width='+windowx+',height='+windowy+',left='+posx+',top='+posy);
  } else {
    var theWin = window.open(theURL,winName,features+',width='+windowx+',height='+windowy+',left=25,top=25');
  }
  theWin.focus();
}


function print_form(report_name,ID) {
  popWin(
    base_url
    +(use_friendly_urls ?
        'print_form/'+report_name+'/'
      : '?mode=print_form&report_name='+report_name+'&ID='
     )
    +ID,
    report_name+'_'+ID,'status=1, scrollbars=1,resizable=1',720,400,1);
}

function print_form_data() {
  var frm = geid('form'), id;
  var fields = [];
  for (var i=0; i<frm.elements.length; i++) {
    id = frm.elements[i].id;
    switch (id) {
      case "command":
      case "goto":
      case "mode":
      case "submode":
      break;
      default:
        fields.push(id+'='+geid_val(id));
      break;
    }
  }
  popWin(
    base_url
    + "?command=print_form_data"
    + "&"+fields.join('&'),'','status=1, scrollbars=1,resizable=1',600,600,1);
  return false;
}

function popup_map(system,page,ID) {
  popWin(system+'/?page='+page+'&ID='+ID+'&print=1',ID,'status=1, scrollbars=1,resizable=1',600,600,1);
}

function popup_help(page) {
  if (page===undefined) {
    popWin(base_url+'?mode=help','help','status=1, scrollbars=1,resizable=1',720,400,1);
  }
  else {
    popWin(base_url+'?mode=help&page='+page,'help','status=1, scrollbars=1,resizable=1',720,400,1);
  }
}

function print_friendly() {
  var theURL;
  if (window.location.search!="") {
    theURL = window.location.href+"&print=1";
  }
  else {
    theURL =
      window.location.href.toString().split('#')[0]+"?print=1" +
      (geid('goto') && geid_val('goto')!="" ? "&goto="+geid_val('goto') : "") +
      (!use_friendly_urls && geid('mode') && geid_val('mode')!="" ? "&mode="+geid_val('mode') : "") +
      (!use_friendly_urls && geid('ID') && geid_val('ID')!="" ? "&ID="+geid_val('ID') : "") +
      (!use_friendly_urls && geid('eventID') && geid_val('eventID')!="" ? "&eventID="+geid_val('eventID') : "") +
      (!use_friendly_urls && geid('report_name') && geid_val('report_name')!="" ? "&report_name="+geid_val('report_name') : "") +
      (geid('filterAggregate') && geid_val('filterAggregate')!="" ? "&filterAggregate="+geid_val('filterAggregate') : "") +
      (geid('filterField') && geid_val('filterField')!="" ? "&filterField="+geid_val('filterField') : "") +
      (geid('filterExact') && geid_val('filterExact')!="" ? "&filterExact="+geid_val('filterExact') : "") +
      (geid('filterValue') && geid_val('filterValue')!="" ? "&filterValue="+geid_val('filterValue') : "") +
      (geid('limit') && geid_val('limit')!="" ? "&limit="+geid_val('limit') : "") +
      (geid('offset') && geid_val('offset')!="" ? "&offset="+geid_val('offset') : "") +
      (geid('search_categories') && geid_val('search_categories')!="" ? "&search_categories="+geid_val('search_categories') : "") +
      (geid('search_keywords') && geid_val('search_keywords')!="" ? "&search_keywords="+geid_val('search_keywords') : "") +
      (geid('search_offset') && geid_val('search_offset')!="" ? "&search_offset="+geid_val('search_offset') : "") +
      (geid('search_type') && geid_val('search_type')!="" ? "&search_type="+geid_val('search_type') : "") +
      (geid('selectID') && geid_val('selectID')!="" ? "&selectID="+geid_val('selectID') : "") +
      (geid('topbar_search') && geid_val('topbar_search')!="" ? "&topbar_search="+geid_val('topbar_search') : "") +
      (geid('sortBy') && geid_val('sortBy')!="" ? "&sortBy="+geid_val('sortBy') : "");
  }
  popWin(theURL,'printFriendly','scrollbars=1,resizable=1,status=1,toolbar=1,menubar=1',600,400,1);
}

function radio_group_get(name) {
  var element_arr = document.getElementsByName(name);
  if(!element_arr) {
    return false;
  }
  for(var i = 0; i < element_arr.length; i++) {
    if(element_arr[i].checked) {
      return element_arr[i].value;
    }
  }
  return false;
}
function radio_group_set(name,val) {
  element_arr = document.getElementsByName(name);
  if(!element_arr) {
    return false;
  }
  for(var i = 0; i < element_arr.length; i++) {
    element_arr[i].checked = false;
    if (element_arr[i].value==val.toString()) {
      element_arr[i].checked = true;
      return true;
    }
  }
  return false;
}

function radio_groups_group_set(val,options_csv) {
  var options_arr = options_csv.split(',');
  for (var i=0; i<options_arr.length; i++) {
    if (geid('form')[options_arr[i]]) {
      if (val==options_arr[i]) {
        geid('form')[options_arr[i]][0].checked=0;
        geid('form')[options_arr[i]][1].checked=1;
      }
      else {
        geid('form')[options_arr[i]][0].checked=1;
        geid('form')[options_arr[i]][1].checked=0;
      }
    }
  }
}


function register_copy_my_details(form) {
  with (form) {
    NFirst.value=my_NFirst.value;
    NMiddle.value=my_NMiddle.value;
    NLast.value=my_NLast.value;
    PEmail.value=my_PEmail.value;
    ATelephone.value=my_ATelephone.value;
  }
}

function register_required(form) {
  if (form.NFirst.value=='' && form.NLast.value==''){
    alert('You must enter a name');
    return false;
  }
  if (form.PEmail.value=='') {
    alert('You must enter a contact email address');
    return false;
  }
  return true;
}

// ************************************
// * Report Filter Operations         *
// ************************************
function report_filter_set(reportID,filter) {
//  alert(filter.settings.ID);
  geid_set('filterField',filter.settings.criterion);
  geid_set('filterExact',filter.settings.matchmode);
  geid_set('filterValue',filter.settings.value);
  geid_set('filterAggregate',filter.settings.aggregate);

  var ff = geid('filterField_'+reportID);
  var fe = geid('filterExact_'+reportID);
  var fv = geid('filterValue_'+reportID);


  for (var i=0; i<ff.options.length; i++) {
    if (ff.options[i].value==filter.settings.criterion+'|'+filter.settings.aggregate) {
      ff.selectedIndex = i;
    }
  }
  for (var i=0; i<fe.options.length; i++) {
    if (fe.options[i].value==filter.settings.matchmode) {
      fe.selectedIndex = i;
    }
  }
  fv.value=filter.settings.value;
}
function filterbar_disable_controls(reportID) {
  geid('btn_go_'+reportID).disabled=true;
  geid('btn_clear_'+reportID).disabled=true;
  geid('btn_save_'+reportID).disabled=true;
}
function filterbar_filterField_onchange(reportID) {
  if(geid_val('filterField_'+reportID)==''){
    geid('filterExact_'+reportID).selectedIndex=0;
    geid_set('filterExact','');
  };
  if(geid_val('filterField_'+reportID)!='' && geid_val('filterExact_'+reportID)==''){
    geid('filterExact_'+reportID).selectedIndex=1;
    geid_set('filterExact','0');
  }
  var ff_arr = geid_val('filterField_'+reportID).split('|');
  geid_set('filterField',ff_arr[0]);
  geid_set('filterAggregate',ff_arr[1]);
  return false;
}
function filterbar_filterExact_onchange(reportID) {
  geid_set('filterExact',geid_val('filterExact_'+reportID));
  if(geid_val('filterExact_'+reportID)==''){
    geid('filterField_'+reportID).selectedIndex=0;
  }
}
function filterbar_go_onclick(reportID,report_name,toolbar){
  filterbar_disable_controls(reportID);
  if (report_name) {
    ajax_report(reportID,report_name,toolbar);
  }
  else {
    geid('form').submit();
  }
}
function filterbar_clear_onclick(reportID,report_name,toolbar){
  filterbar_disable_controls(reportID);
  geid_set('limit',10);
  geid_set('offset',0);
  geid_set('filterAggregate','');
  geid_set('filterExact','');
  geid_set('filterField','');
  geid_set('filterValue','');
  geid_set('filterExact_'+reportID,'');
  geid_set('filterValue_'+reportID,'');
  geid('filterField_'+reportID,'');
  if (geid('limit_'+reportID) && geid('limit_'+reportID).selectedIndex) { geid('limit_'+reportID).selectedIndex=0; }
  if (geid('offset_'+reportID) && geid('offset_'+reportID).selectedIndex) { geid('offset_'+reportID).selectedIndex=0;}
  if (report_name) {
    ajax_report(reportID,report_name,toolbar);
  }
  else {
    geid('form').submit();
  }
}
function filterbar_save_onclick(reportID,report_name,toolbar){
  var h, j;
  h = "Enter name for new Preset Filter"
     +"<div style='padding-top:10px;'>"
     +"<table class='minimal' summary='Grid layout for popup form'>\n"
     +"  <tr>\n"
     +"    <td style='width:50px;'>Name</td>\n"
     +"    <td><input type='text' id='filter_name' onkeyup=\"geid('btn_ok').disabled = this.value.length==0\" "
     +"class='formField fl' style='width:100px;' value='' /></td>\n"
     +"  </tr>\n"
     +"</table>\n"
     +"</div>";
  j = "if(geid_val('filter_name')==''){return false;}"
     +"filterbar_disable_controls('"+reportID+"');"
     +"geid_set('submode','filter_add');"
     +"geid_set('targetValue',geid_val('filter_name'));"
     +"geid_set('targetReportID','"+reportID+"');"
//     +"alert(geid('filterField').value);"
     +"geid('form').submit();"
  popup_dialog("Filter Save",h,200,260,'OK','Cancel',j,'filter_name');
  geid('btn_ok').disabled=true;
}


function select_item(ID) {
  geid('selectID').value =    ID;
  geid('form').submit();
}


function select_YYYY_MM(YYYY,MM,targetReportName) {
  geid('YYYY').value =    YYYY;
  geid('MM').value =      MM;
  geid('anchor').value =  targetReportName;
  geid('form').submit();
}

function setBackground(targDiv,color) {
  if (isW3C) { // DOM3 = IE5, NS6
    var div = geid(targDiv);
    if (div) {
      div.style.background = color;
    }
  }
}
function setBlock(targDiv,show) {
  if (isW3C) { // DOM3 = IE5, NS6
    var div = geid(targDiv);
    if (div) {
      div.style.display = (show ? "block" : "none");
    }
  }
}

function setDisplay(targDiv,show) {
  if (isW3C) { // DOM3 = IE5, NS6
    var div = geid(targDiv);
    if (div) {
      div.style.display = (show ? "" : "none");
    }
  }
}
 
function signup_required(form) {
  if ((form.PUsername && form.PUsername.value=='')) {
    alert('You must enter a requested username');
    return false;
  }
  if ((form.PEmail && form.PEmail.value=='')) {
    alert('You must enter a valid email address');
    return false;
  }
  return true;
}

function show_section(sections_arr,section,col_normal,col_selected) {
  geid('selected_section').value=section;
  for (var i=0; i<sections_arr.length; i++) {
    var _section = sections_arr[i];
    setBackground('section_'+_section+'_heading',(section==_section ? col_selected : col_normal));
    setDisplay('section_'+_section,(section==_section));
  }
  return true;
}

function LTrim(str) {
  var whitespace = new String(" \t\n\r");
  var s = new String(str);
  if (whitespace.indexOf(s.charAt(0)) != -1) {
    var j=0, i = s.length;
    while (j < i && whitespace.indexOf(s.charAt(j)) != -1)
      j++;
    s = s.substring(j, i);
  }
  return s;
}

function RTrim(str) {
  var whitespace = new String(" \t\n\r");
  var s = new String(str);
  if (whitespace.indexOf(s.charAt(s.length-1)) != -1) {
    var i = s.length - 1;
    while (i >= 0 && whitespace.indexOf(s.charAt(i)) != -1)
      i--;
    s = s.substring(0, i+1);
  }
  return s;
}
function round(number,X) {
// rounds number to X decimal places, defaults to 2
  X = (!X ? 2 : X);
  return Math.round(number*Math.pow(10,X))/Math.pow(10,X);
}

function search_offset(offset,type){
  geid_set('search_offset',offset);
  geid_set('search_type',type);
  geid('form').submit();
  return false;
}

function search_setup_date_range() {
  geid('_search_date_start').innerHTML = date_selector_draw('_search_date_start',geid_val('search_date_start'));
  geid('_search_date_end').innerHTML =   date_selector_draw('_search_date_end',geid_val('search_date_end'));
}
function search_results_go() {
  if (geid('search_sites_selector')) {
    var sites_arr = 	[];
    var selector = 	geid('search_sites_selector');
    for (var i=0; i<selector.options.length; i++) {
      if (selector.options[i].selected){
        sites_arr.push(selector.options[i].value);
      }
    }
    geid_set('search_sites',sites_arr.join(','));
  }
  var start = geid_val('_search_date_start_yyyy')+"-"+geid_val('_search_date_start_mm')+"-"+geid_val('_search_date_start_dd');
  var end =   geid_val('_search_date_end_yyyy')+"-"+geid_val('_search_date_end_mm')+"-"+geid_val('_search_date_end_dd');

  var start_val = geid_val('_search_date_start_yyyy')*10000 + geid_val('_search_date_start_mm')*100 + geid_val('_search_date_start_dd');
  var end_val =   geid_val('_search_date_end_yyyy')*10000 +   geid_val('_search_date_end_mm')*100   + geid_val('_search_date_end_dd');

  if (start_val>end_val && end_val!=0){
    var tmp = start; start = end; end = tmp;
  }

  geid_set('mode','');
  geid_set('search_offset','0');
  geid_set('search_categories',geid('_search_categories') ? geid_val('_search_categories') : "");

  geid_set('search_date_start',start);
  geid_set('search_date_end',  end);

  geid_set('search_keywords',geid('_search_keywords') ? geid_val('_search_keywords') : "");
  geid_set('search_text',geid_val('_search_text'));
  geid_set('search_type',geid_val('_search_type'));
  geid('form').submit();
}
function search_go() {
  geid_set('goto','search_results');
  geid_set('mode','');
  geid_set('search_offset','0');
  geid_set('search_type','*');
  geid('form').submit();
}

function topbar_search_go() {
  geid_set('search_text',geid_val('topbar_search'));
  search_go();
}
function Trim(str) {
  return RTrim(LTrim(str));
}
function two_dp(amount){
  var i = parseFloat(amount);
  if(isNaN(i)) { i = 0.00; }
  var minus = '';
  if(i < 0) { minus = '-'; }
  i = Math.abs(i);
  i = parseInt((i + .005) * 100);
  i = i / 100;
  var s = new String(i);
  if(s.indexOf('.') < 0) { s += '.00'; }
  if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
  s = minus + s;
  return s;
}

function textCounter(field, countfield, maxlimit) {
  if (field.value.length > maxlimit) // if too long...trim it!
    field.value = field.value.substring(0, maxlimit);
  else
    countfield.value = maxlimit - field.value.length;
}

function payment_method_change(offline,id_method,id_card_name,id_card_number,id_card_exp_mm,id_card_exp_yy) {
  geid(id_card_name).disabled=offline;
  geid(id_card_number).disabled=offline;
  geid(id_card_exp_mm).disabled=offline;
  geid(id_card_exp_yy).disabled=offline;
  geid(id_card_name).style.backgroundColor=(offline ? '#e0e0e0' : '');
  geid(id_card_number).style.backgroundColor=(offline ? '#e0e0e0' : '');
  geid(id_card_exp_mm).style.backgroundColor=(offline ? '#e0e0e0' : '');
  geid(id_card_exp_yy).style.backgroundColor=(offline ? '#e0e0e0' : '');
}
function validate_payment_details(err_arr,id_method,id_card_name,id_card_number,id_card_ex_mm,id_card_exp_yy) {
  var n = err_arr.length;
  if (geid(id_method).value==''){
    err_arr[n++]= pad(''+n+')',4) +"Payment Method is missing";
  }
  if (geid(id_card_name).value ==''){
    err_arr[n++]= pad(''+n+')',4) +"CardHolder Name is missing";
  }
  if (geid(id_card_number).value.replace(/[^0-9]+/ig,'')==''){
    err_arr[n++]=pad(''+n+')',4)+"Credit card number missing";
  }
  else {
    if (geid(id_card_number).value.replace(/[^0-9 ]+/ig,'')!=geid(id_card_number).value){
      err_arr[n++]=pad(''+n+')',4)+"Credit card number contains invalid characters";
    }
    else {
      if (geid(id_card_number).value.replace(/[^0-9]+/ig,'').length!=16) {
//        err_arr[n++]= pad(''+n+')',4)+"Credit card number must have 16 digits";
      }
    }
  }
  if (geid(id_card_ex_mm).value.length==0 || geid(id_card_ex_mm).value.replace(/[^0-9]+/ig,'')!=geid(id_card_ex_mm).value || parseFloat(geid(id_card_ex_mm).value)<1 || parseFloat(geid(id_card_ex_mm).value)>12) {
    err_arr[n++]= pad(''+n+')',4)+"Expiry Month value must be between 01 and 12";
  }
  var this_year=new Date().getYear().toString().substr(2,2);
  if (geid(id_card_exp_yy).value.length==0 || geid(id_card_exp_yy).value.replace(/[^0-9]+/ig,'')!=geid(id_card_exp_yy).value || parseFloat(geid(id_card_exp_yy).value)<parseFloat(this_year) || parseFloat(geid(id_card_exp_yy).value)>parseFloat(this_year)+10) {
    err_arr[n++]= pad(''+n+')',4)+"Expiry Year value outside acceptable range ("+this_year+" to "+(parseFloat(this_year)+10)+")";
  }
  return err_arr;
}
function version(ver) {
  var name = ver.replace(/\./g,'_');
  popWin('http://www.ecclesiact.com/build?build='+ver,name,'scrollbars=1,resizable=1,status=0',800,600,'centre');
}
function view_event_registrants(eventID,width,height) {
  popWin(
    base_url
    +(use_friendly_urls ?
        'view_event_registrants/?'
      : '?page=view_event_registrants&'
     )
    +'print=1&eventID='+eventID,'eventRegistrants','status=1, scrollbars=1,resizable=1',width,height,1
  );
}

function view_credit_memo(ID,width,height) {
  popWin(
    base_url
    +(use_friendly_urls ?
        'view_credit_memo/?'
      : '?page=view_credit_memo&'
     )
    +'print=2&ID='+ID,'','status=1,scrollbars=1,resizable=1,menubar=1',width,height,1
  );
}

function view_order_details(ID,width,height) {
  popWin(
    base_url
    +(use_friendly_urls ?
        'view_order/?'
      : '?page=view_order&'
     )
    +'print=2&ID='+ID,'','status=1,scrollbars=1,resizable=1,menubar=1',width,height,1
  );
}



/**
 * COMMON DHTML FUNCTIONS (comments by original author)
 *
 * These are handy functions I use all the time.
 * By Seth Banks (webmaster at subimage dot com)
 * http://www.subimage.com/
 * Up to date code can be found at http://www.subimage.com/dhtml/
 * This code is free for you to use anywhere, just keep this comment block.
 */

function addEvent(obj, evType, fn){
 if (obj.addEventListener){
    obj.addEventListener(evType, fn, true);
    return true;
 } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
 } else {
    return false;
 }
}
function removeEvent(obj, evType, fn, useCapture){
  if (obj.removeEventListener){
    obj.removeEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.detachEvent){
    var r = obj.detachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be removed");
    return false;
  }
}

/**
 * Code below taken from - http://www.evolt.org/article/document_body_doctype_switching_and_more/17/30655/
 * Modified 4/22/04 to work with Opera/Moz (by webmaster at subimage dot com)
 * Gets the full width/height because it's different for most browsers.
 */
function getViewportHeight() {
  if (window.innerHeight!=window.undefined) return window.innerHeight;
  if (document.compatMode=='CSS1Compat') return document.documentElement.clientHeight;
  if (document.body) return document.body.clientHeight; 
  return window.undefined; 
}
function getViewportWidth() {
  var offset = 17;
  var width = null;
  if (window.innerWidth!=window.undefined) return window.innerWidth; 
  if (document.compatMode=='CSS1Compat') return document.documentElement.clientWidth; 
  if (document.body) return document.body.clientWidth; 
}
/**
 * Gets the real scroll top
 */
function getScrollTop() {
  if (self.pageYOffset) {
    // all except Explorer
    return self.pageYOffset;
  }
  else if (document.documentElement && document.documentElement.scrollTop) {
    // Explorer 6 Strict
    return document.documentElement.scrollTop;
  }
  else if (document.body){ // all other Explorers
    return document.body.scrollTop;
  }
}
function getScrollLeft() {
  if (self.pageXOffset){
    // all except Explorer
    return self.pageXOffset;
  }
  else if (document.documentElement && document.documentElement.scrollLeft) {
    // Explorer 6 Strict
    return document.documentElement.scrollLeft;
  }
  else if (document.body) {
    // all other Explorers
    return document.body.scrollLeft;
  }
}
