/*
 * Site-Wide Support Scripts    
 * =========================
 * Scripts that must be available on each and every C21 page.   
 *
 */
//Install common browser fixes
var g_pBrowser = new Object();
g_pBrowser.bIsMsIe = false;
g_pBrowser.bIsFirefox = false;
g_pBrowser.bIsChrome = false;
g_pBrowser.bIsSafari = false;
g_pBrowser.bIsOpera = false;
g_pBrowser.fVersionMajor = 1;

//Shut-up curvy corners, thanks.
curvyCornersVerbose = false;   

try {
   if( navigator.appName == "Microsoft Internet Explorer" ) {
      // Make sure Opera isn't pretending to be cool
      if (navigator.userAgent.indexOf('Opera') == -1) {
         g_pBrowser.bIsMsIe = true;

         // IE specific background cacheing
         document.execCommand("BackgroundImageCache", false, true);
      }
   }

   // Determine browser
   if (navigator.userAgent.indexOf('Firefox') != -1) {
      g_pBrowser.bIsFirefox = true;
   }
   if (navigator.userAgent.indexOf('Chrome') != -1) {
      g_pBrowser.bIsChrome = true;
   }
   if (navigator.userAgent.indexOf('Safari') != -1) {
      g_pBrowser.bIsSafari = true;
   }
   if (navigator.userAgent.indexOf('Opera') != -1) {
      g_pBrowser.bIsOpera = true;
   }

   if(g_pBrowser.bIsMsIe ) {
      g_pBrowser.fVersionMajor = parseFloat(navigator.appVersion.split("MSIE")[1]);
   } else {
      g_pBrowser.fVersionMajor = parseInt(navigator.appVersion);
   }
} catch(err) {}

/**
 * Cyber Core Utilities
 */
var CyberCore = new function() {

   /**
    * Get a DOM object
    * @param strObject either a DOM element reference (which will simply pass through)
    *                  or an id to look up
    * @return the resulting DOM element
    */
   this.getObj = function(strObject) {
      if (typeof strObject == 'string') {
         return document.getElementById(strObject);
      }
      return strObject;
   }   

   /**
    * Put an item into an array, if it is not already an array
    * @param pObj the object to put into an array
    * @return the resulting array
    */
   this.makeArray = function(pObj) {
      if(pObj.constructor===Array)
         return pObj;
      else return [pObj];
   }

   /**
    * Determine if a DOM element has a CSS class
    * @param pPop the DOM element reference or id
    * @param strClass the CSS class
    */
   this.hasClass = function(pPop, strClass){
      pPop = CyberCore.getObj(pPop);

      if( pPop && pPop.className ) {
         return pPop.className.match(new RegExp('(\\s|^)'+ strClass +'(\\s|$)'));
      }
      return false;
   }

   /**
    * Get the text content of a node
    * @param el the DOM element reference or id
    */
   this.getText = function(el) {
      var el = CyberCore.getObj(el);

      //     Sane browsers  || IE           || IE
      return el.textContent || el.innerText || el.text;
   }

   /**
    * Set the text content of a node
    * @param strObject the DOM element reference or id
    * @param sText
    */
   this.setText = function(strObject,sText) {
      var strObject = CyberCore.getObj(strObject);
      strObject[typeof(strObject.innerText)!=="string"?"textContent":"innerText"] = sText;
   }

   /**
    * Add a CSS class to a DOM element
    * @param pPop the DOM element reference or id
    * @param strClass the CSS class
    */
   this.addClass = function(pPop, strClass){
      pPop = CyberCore.getObj(pPop);

      if( pPop ) {
         if (!CyberCore.hasClass(pPop, strClass)) {
            pPop.className += " " + strClass;
            return true;
         }
      }
      return false;
   }

   /**
    * Remove a CSS class from a DOM element
    * @param pPop the DOM element reference or id
    * @param strClass the CSS class
    */
   this.removeClass = function(pPop, strClass){
      pPop = CyberCore.getObj(pPop);

      if( pPop ) {
         if (CyberCore.hasClass(pPop, strClass)) {
            var reg = new RegExp('(\\s|^)'+ strClass +'(\\s|$)');
            pPop.className = pPop.className.replace(reg, '$2');
            return true;
         }
      }
      return false;
   }
   
   /**
    * Add a CSS class to all the child nodes of a tag name in a container element
    * @param pContainer the DOM element reference or id
    * @param strTagType the tag name to add the CSS class to
    * @param strClass the class name
    */
   this.addClassToChildTags = function( pContainer, strTagType, strClass ) {
      pContainer = CyberCore.getObj(pContainer);

      var aChildren = pContainer.getElementsByTagName(strTagType);
      if( aChildren && aChildren.length > 0 ) {
         for( var i=0; i < aChildren.length; i++ ) {
            CyberCore.addClass( aChildren[i], strClass );
         }
      }
   }
   
   /**
    * Remove a CSS class from all the child nodes of a tag name in a container element
    * @param pContainer the DOM element reference or id
    * @param strTagType the tag name to remove the CSS class from
    * @param strClass the class name
    */
   this.removeClassFromChildTags = function( pContainer, strTagType, strClass ) {
      pContainer = CyberCore.getObj(pContainer);

      var aChildren = pContainer.getElementsByTagName(strTagType);
      if( aChildren && aChildren.length > 0 ) {
         for( var i=0; i < aChildren.length; i++ ) {
            CyberCore.removeClass( aChildren[i], strClass );
         }
      }
   }
   
   /**
    * Trim whitespace from a string
    * @param stringToTrim
    */
   this.trim = function(stringToTrim) {
      return stringToTrim.replace(/^\s+|\s+$/g,"");
   }
   
   /**
    * Trim whitespace from the left side of a string
    * @param stringToTrim
    */
   this.ltrim = function(stringToTrim) {
      return stringToTrim.replace(/^\s+/,"");
   }
   
   /**
    * Trim whitespace from the right side of a string
    * @param stringToTrim
    */
   this.rtrim = function(stringToTrim) {
      return stringToTrim.replace(/\s+$/,"");
   }
   
   /**
    * Get the width of a DOM element
    * @param pObj the DOM element reference
    */
   this.findWidth = function(pObj)
   {
      var cursize = 0;

      // W3C                      || IE
      if (document.getElementById || document.all) {
         cursize = pObj.offsetWidth;

      // NN4
      } else if (document.layers)
         cursize = pObj.width;
   
      return cursize;
   }

   
   /**
    * Get the height of a DOM element
    * @param pObj the DOM element reference
    */
   this.findHeight = function(pObj)
   {
      var cursize = 0;

      // W3C                      || IE
      if (document.getElementById || document.all) {
         cursize = pObj.offsetHeight;

      // NN4
      } else if (document.layers)
         cursize = pObj.height;
   
      return cursize;
   }

   /**
    * Get the absolute X position of a DOM element
    * @param pObj the DOM element reference
    */
   this.findPosX =  function(pObj)
   {
      var curleft = 0;

      // W3C                      || IE
      if (document.getElementById || document.all) {
         while (pObj.offsetParent) {
            curleft += pObj.offsetLeft;
            pObj = pObj.offsetParent;
         }

      // NN4
      } else if (document.layers)
         curleft += pObj.x;
   
      return curleft;
   }

   /**
    * Get the absolute Y position of a DOM element
    * @param pObj the DOM element reference
    */
   this.findPosY = function(pObj)
   {
      var curtop = 0;

      // W3C                      || IE
      if (document.getElementById || document.all) {
         if( !pObj.offsetParent ){
            curtop += pObj.offsetTop;
         }
         while (pObj.offsetParent) {
            curtop += pObj.offsetTop;
            pObj = pObj.offsetParent;
         }

      // NN4
      } else if (document.layers)
         curtop += pObj.y;
   
      return curtop;
   }
   
   /**
    * Add an event to a DOM element
    * @param pElement the DOM element reference
    * @param strEventType event type (ex: 'click')
    * @param pFunction function to call
    * @param bUseCapture
    * @return true if the call succeeded, otherwise false
    */
   this.addEvent = function(pElement, strEventType, pFunction, bUseCapture) {
      // W3C
      if (pElement.addEventListener) {
         pElement.addEventListener(strEventType, pFunction, bUseCapture);
         return true;

      // IE
      } else if (pElement.attachEvent) {
         var r = pElement.attachEvent('on' + strEventType, pFunction);
         return r;
      } else {
         return false;
      }
   }

   /**
    * Remove an event from a DOM element
    * @param pElement the DOM element reference
    * @param strEventType
    * @param pFunction
    * @param bUseCapture
    * @return true if the call succeeded, otherwise false
    */
   this.removeEvent = function(pElement, strEventType, pFunction, bUseCapture) {
      if(!pElement)
         pElement = document;

      // W3C
      if (pElement.removeEventListener) {
         var strTemp = strEventType.replace(/^on/i, '');
         pElement.removeEventListener(strTemp, pFunction, bUseCapture );
         return true;

      // IE
      } else if (pElement.detachEvent) {
         pElement.detachEvent('on' + strEventType, pFunction );
         return true;
      } else {
         return false;
      }
   }

   /**
    * Get the pixels that the page is scrolled upward
    */
   this.getScrollTop = function() { 
      //     Never exists...  || <html> tag scrollTop               || <body> tag scrollTop
      return this.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; 
   }
   
   /**
    * Disable or enable all elements in the specified form
    * @param pContainer the DOM element reference or id (for the form)
    * @param bDisabled the disable status
    */
   this.disableFormElements = function( pContainer, bDisabled ) {
      pContainer = CyberCore.getObj(pContainer);

      var aChildren = pContainer.getElementsByTagName('input');
      if( aChildren && aChildren.length > 0 ) {
         for( var i=0; i < aChildren.length; i++ ) {
            aChildren[i].disabled = bDisabled;
         }
      }
      aChildren = pContainer.getElementsByTagName('select');
      if( aChildren && aChildren.length > 0 ) {
         for( var i=0; i < aChildren.length; i++ ) {
            aChildren[i].disabled = bDisabled;
         }
      }
      aChildren = pContainer.getElementsByTagName('checkbox');
      if( aChildren && aChildren.length > 0 ) {
         for( var i=0; i < aChildren.length; i++ ) {
            aChildren[i].disabled = bDisabled;
         }
      }
      
   }

   /**
    * Gets the value from a select box.
    * @param elem the DOM element reference or id
    * @return string representing the select box value
    */
   this.getSelectedValue = function(elem) {
      var pObj = CyberCore.getObj(elem);
      if( pObj.selectedIndex != null ) {
         return pObj[pObj.selectedIndex].value;
      } else {
         return pObj.value;
      }
   }

   /**
    * Sets a value for a select box.
    * @param elem the DOM element reference or id
    * @param strValue the value to set the select box to
    */
   this.setSelectedValue = function(elem, strValue) {
      var pObj = CyberCore.getObj(elem);
      if( pObj.selectedIndex != null ) {
         for(var i = 0; i < pObj.length; i++) {
            if(pObj[i].value == strValue) {
               pObj.selectedIndex = i;
               return;
            }
         }
      } else {
         pObj.value = strValue;
      }
   }
   
   /**
    * Get all elements with the specified class name
    * @param cl the class name
    */
   this.getElementsByClassName = function(cl) {
      // Use native document.getElementsByClassName, if it exists
      if (document.getElementsByClassName) {
         return document.getElementsByClassName(cl);
      }

      var retnode = [];
      var myclass = new RegExp('\\b'+cl+'\\b');
      var elem = document.getElementsByTagName('*');
      for (var i = 0; i < elem.length; i++) {
         var classes = elem[i].className;
         if (myclass.test(classes)) retnode.push(elem[i]);
      }
      return retnode;
   }
   
   /**
    * Get the event information in a browser-neutral format
    * @param e the event (more useful if a mouse click)
    * @return an object with iPosX, iPosY, and pTarget
    */
   this.getEventInformation = function(e) {
      var pEventInfo = new Object();
      var posx = 0;
      var posy = 0;
      if (!e) var e = window.event;
      if (e.pageX || e.pageY)    {
         posx = e.pageX;
         posy = e.pageY;
      }
      else if (e.clientX || e.clientY)    {
         posx = e.clientX + document.body.scrollLeft
            + document.documentElement.scrollLeft;
         posy = e.clientY + document.body.scrollTop
            + document.documentElement.scrollTop;
      }
   
      pEventInfo.iPosX = posx;
      pEventInfo.iPosY = posy;
      pEventInfo.pTarget = e.relatedTarget || e.fromElement;
   
      return pEventInfo;
   }
   
   /**
    * Uses the strDefaultValue custom attribute to determine if form data was entered
    * @param pContainer the container to check input elements in
    * @return true if data was entered, false if no data was entered or pContainer doesn't exist
    */
   this.formDataEnteredInContainer = function(pContainer) {
      pContainer = CyberCore.getObj(pContainer);

      if( !pContainer ) {
         return false;
      }
      var bDataEntered = false;
      var aChildren = pContainer.getElementsByTagName('input');
      for( var i=0; i < aChildren.length; i++ ) {
         if( (aChildren[i].type == 'text'  || aChildren[i].type == 'hidden') && aChildren[i].name != 'svf' ) {
            if( aChildren[i].strDefaultValue ) {
               if( !((aChildren[i].value == aChildren[i].strDefaultValue) || (aChildren[i].value == '')) ) bDataEntered = true;
            } else {
               if( aChildren[i].value != '' ) bDataEntered = true;
            }
         }
         return bDataEntered;
      }
      return false;
   }
   
   /**
    * Clear the value for the target input of the specified event
    * IF it is equal to the default value
    * (ex: User clicks on form field, which calls this function onfocus)
    * @param e an event
    */
   this.clearDefaultValue = function(e) {
      var pFormField = window.event ? window.event.srcElement : e ? e.target : null;
      if (!pFormField) return;
      if (pFormField.value == pFormField.strDefaultValue) {
         pFormField.value = '';
      }
   }
   
   /**
    * Set the value for the target input of the specified event
    * to the default value IF it is empty
    * (ex: User clicks away from form field, which calls this function onblur)
    * @param e an event
    */
   this.setDefaultValue = function(e) {
      var pFormField = window.event ? window.event.srcElement : e ? e.target : null;
      if (!pFormField) return;
       
      if (pFormField.value == '' && pFormField.strDefaultValue ) {
         pFormField.value = pFormField.strDefaultValue;
      }
   }
   
   /**
    * Bind a default value to a field in a form
    * @param strFormId the form DOM element id
    * @param strFieldName the field name
    * @param strDefaultValue
    */
   this.bindDefaultValue = function( strFormId, strFieldName, strDefaultValue ) 
   {
      var pForm = document.getElementById( strFormId );
      if( pForm ) {
         // TODO: Couldn't you just use form.getElementsByName?
         var aChildren = pForm.getElementsByTagName('input');
         if( aChildren && aChildren.length > 0 ) {
            for( var i=0; i < aChildren.length; i++ ) {
               if( aChildren[i].name == strFieldName ) {
                  aChildren[i].strDefaultValue = strDefaultValue;
                  CyberCore.addEvent(aChildren[i], 'focus', function(e){CyberCore.clearDefaultValue(e);}, false);
                  CyberCore.addEvent(aChildren[i], 'blur',  function(e){CyberCore.setDefaultValue(e);}, false);
               }
            }
         }
      }
   }

   /**
    * Set all the form's blank fields to their strDefaultValue
    * @param pForm the DOM element reference or id
    */
   this.initializeDefaults = function( pForm ) {
      pForm = CyberCore.getObj(pForm);

      if( pForm ) {
         for( var i=0; i < pForm.elements.length; i++ ) {
            if( pForm.elements[i].type == 'text'  || pForm.elements[i].type == 'hidden' ) {
               if( pForm.elements[i].strDefaultValue ) {
                  if (pForm.elements[i].value == '' && pForm.elements[i].strDefaultValue ) {
                     pForm.elements[i].value = pForm.elements[i].strDefaultValue;
                  }
               }
            }
         }
      }
   }

   /**
    * Blank out all the form's fields that are set to default values
    * @param pForm the DOM element reference
    */
   this.removeAllDefaultData = function( pForm ) {
      if( pForm ) {
         for( var i=0; i < pForm.elements.length; i++ ) {
            if( pForm.elements[i].type == 'text'  || pForm.elements[i].type == 'hidden' ) {
               if( pForm.elements[i].strDefaultValue ) {
                  if( pForm.elements[i].value == pForm.elements[i].strDefaultValue ) {
                     pForm.elements[i].value = '';
                  }
               }
            }
         }
      }
   }
   
   /**
    * If the object exists, set the innerHTML value
    * @param strObjId
    * @param strValue
    */
   this.setInnerHtml = function(strObjId, strValue) {
      var pObj = CyberCore.getObj(strObjId);
      if( pObj ) {
         pObj.innerHTML = strValue;
      }
   }
   
   /**
    * Determine whether an event's last keystroke was the ENTER key
    * @param e the event to test against
    * @return true if ENTER was pressed, otherwise false
    */
   this.keystrokeWasEnter = function(e) {
      var iCharCode = (e.which == undefined) ? e.keyCode : e.which;
      if (iCharCode == 13) {
         return true;
      }
      return false;
   }
   
   /**
    * If the specified input has an empty value, set the value
    * @param strObjId the DOM element id
    * @param strValue
    */
   this.setOnEmpty = function(strObjId, strValue) {
      var pObj = document.getElementById(strObjId);
      if( pObj ) {
         if( pObj.value == '' ) {
            pObj.value = strValue;
         }
      }
   }
   
   /**
    * Get the int representation of a field value
    * @param strField the DOM element id
    * @param iDefault if the element does not exist, default to this
    * @return an int representation of the field value
    */
   this.getHiddenFieldIntValue = function( strField, iDefault ) {
      if( iDefault == null ) {
          iDefault = 0;
      }
      var pField = document.getElementById(strField);
      if( pField ) {
         if( pField.value != '' ) {
            return parseInt( pField.value );
         }
      }
      return iDefault;
   }
   
   /**
    * Get the float representation of a field value
    * @param strField the DOM element id
    * @return a float representation of the hidden field value
    *         OR 0 if the field does not exist
    */
   this.getHiddenFieldFloatValue = function( strField ) {
      var pField = document.getElementById(strField);
      if( pField ) {
         if( pField.value != '' ) {
            return parseFloat( pField.value );
         }
      }
      return 0;
   }
   
   /**
    * Get a specified value from a cookie
    * @param offset
    * @return URL unescaped Cookie Value
    */
   this.getCookieVal = function(offset) {
      var endstr = document.cookie.indexOf (";", offset);
   
      if ( endstr == -1 )
         endstr = document.cookie.length;
      return(unescape(document.cookie.substring(offset, endstr)));
   }
   
   /**
    * Retrieve cookie from users browser
    * @param name
    * @return value in cookie
    */
   this.getCookie = function(name) {
      var arg = name + "=";
      var alen = arg.length;
      var clen = document.cookie.length;
      var i = 0;
   
      while ( i < clen ) {
         var j = i + alen;
         if ( document.cookie.substring(i, j) == arg ) return(CyberCore.getCookieVal (j));
         i = document.cookie.indexOf(" ", i) + 1;
         if ( i == 0 ) break;
      }
   
      return(null);
   }
   
   /**
    * Store a cookie in the users browser
    * @param name
    * @param value
    * @param expires expiration date
    * @param path
    * @param domain
    * @param secure security
    */
   this.setCookie = function(name,value,expires,path,domain,secure) {
      document.cookie = name + "=" + escape (value) +
                        ((expires) ? "; expires=" + expires.toGMTString() : "") +
                        ((path) ? "; path=" + path : "") +
                        ((domain) ? "; domain=" + domain : "") +
                        ((secure) ? "; secure" : "");
   }
  
   /**
    * Submits a form with proper call of onSubmit handler if exists.
    * @param pForm
    */ 
   this.submitForm = function(pForm) {
      var pFormObj = CyberCore.getObj(pForm);
      if( pFormObj ) {
         if( pFormObj.onsubmit ) {
            if( pFormObj.onsubmit() ) {
               pFormObj.submit();
            }
         } else {
            pFormObj.submit();
         }
      }
   }

   /**
    * Submit the field's form if the user pressed enter
    * @param e the event to check against
    * @param pField the DOM element reference a field in the form
    */
   this.submitFormOnEnter = function(e, pField) {
      if( pField ) {
         if( CyberCore.keystrokeWasEnter(e)) {
            if( pField.form ) {
               if( pField.form.onsubmit ) {
                  pField.form.onsubmit();
               }
               pField.form.submit();
            }
         }
      }
   }
   
   /**
    * Call the specified function if the user pressed enter
    * @param e the event to check against
    * @param func the function to call
    * @return true if the keystroke was enter, otherwise false
    */
   this.callFunctionOnEnter = function(e, func) {
       if ( CyberCore.keystrokeWasEnter(e) ) {
         func();
         return true;
       } else {
         return false;
       }
   }

   /**
    * Get the specified parameter from the query string
    * @param strParamName the parameter key
    * @return the parameter value
    */
   this.getQueryStringParameter = function(strParamName) {
      var aURLParts = window.location.href.split('?');
      if(aURLParts[1]) {
         var aParamPairs = aURLParts[1].split('&');
         for(var i = 0; i < aParamPairs.length; i ++) {
            var aKeyValuePair = aParamPairs[i].split('=');
            if(aKeyValuePair[0]==strParamName) return aKeyValuePair[1];
         }
      }
      return '';
   } 

   /**
    * Bind a function to a scope
    * @param scope  the scope to bind to 
    * @param fn     the function to bind
    * @param ...    (optional) the arguments to pass to fn when it is called
    * @return a function that will use the specified scope and arguments
    */
   this.bindScope = function ( scope, fn ) {
      // Since the arguments variable is an object and
      // not an array we can not use the slice method directly
      var bindArgs = CyberCore.argumentsToArray(arguments);

      // Skip scope and fn; There is no reason to pass these
      // into the function we are calling since they will 
      // already be available
      bindArgs.splice(0, 2);

      return function() {
         // Arguments specified at trigger-time are concatenated
         // to those arguments specified at bind-time
         var triggerArgs = CyberCore.argumentsToArray(arguments);
         return fn.apply(scope, bindArgs.concat(triggerArgs));
      }
   }

   /**
    * Converts an arguments object to an array
    * @param obj  the object to convert to an array
    * @return the resulting array
    */
   this.argumentsToArray = function( obj ) {
      var args = [];

      for (var i = 0; i < obj.length; i++)
      {
         args[i] = obj[i];
      }

      return args;
   }

   /**
    * For C21 Support
    * @param pFunc
    */
   this.queueCommand = function( pFunc ) {
      RfgQueueCommand( pFunc );
   }
}


/**
 * Get the X position of the mouse cursor
 * @param objMouseEvent mouse event
 * @return mouse position relative to document in pixels
 */
function CyberGetMouseXPosition(objMouseEvent) 
{
   var iPosition = 0;
   
   if ( objMouseEvent.pageX ) {
      iPosition = objMouseEvent.pageX;
   }
   else {
      if ( objMouseEvent.clientX ) {
         if ( g_eCyberBrowserType == CYBER_BROWSER_TYPE_GECKO ) {
            iPosition = objMouseEvent.clientX + document.body.scrollLeft;
         }
         else {
            iPosition = objMouseEvent.clientX;
         }         
      }
   }

   return iPosition;
}

/**
 * Get the Y position of the mouse cursor
 * @param objMouseEvent mouse event
 * @return mouse position relative to document in pixels
 */
function CyberGetMouseYPosition(objMouseEvent) 
{
   var iPosition = 0;
   if ( objMouseEvent.pageY ) {
      iPosition = objMouseEvent.pageY;
   } else {
      if ( objMouseEvent.clientY ) {
         if ( g_eCyberBrowserType == CYBER_BROWSER_TYPE_GECKO ) {
            iPosition = objMouseEvent.clientY + document.body.scrollTop;
         } else {
            iPosition = objMouseEvent.clientY;
         }
      }
   }

   return iPosition;
}
