//CentricsBaseAPI.js
//This file contains all the 'base' functionality for javascript usage, mostly dealing with object
//retreval and event differences between IE & Mozilla

//Gets object from string id, or pass through if an object is passed in
function getObject(obj)
{
   var loadedObj = null;
   if (typeof obj == "string")
   {
      if (document.getElementById)
      {
         loadedObj = document.getElementById(obj);
         if (loadedObj == null && document.getElementsByName)
         {
            //this is here to support FireFox, as getElementById only
            //looks at ids where as in IE it falls back to name if not
            //found by ID
            var colObjs = document.getElementsByName(obj);
            if (colObjs.length > 0)
            {
               loadedObj = colObjs[0];
            }
         }
      }
      else if (document.all)
      {
         loadedObj = document.all(obj);
      }
   }
   else
   {
      loadedObj = obj;
   }
   
   return loadedObj;
}

// Gets the currently applied style of an element on the page
function getStyle(oElm, strCssRule)
{
   var strValue = "";
   
   if (document.defaultView && document.defaultView.getComputedStyle)
   {
      strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
   }
   else if (oElm.currentStyle)
   {
      strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1)
      {
         return p1.toUpperCase();
      });
      
      strValue = oElm.currentStyle[strCssRule];
   }
   
   return strValue;
}

function toHex(N) {
   if (N == null)
   {
      return "00";
   }
   
   N = parseInt(N); 
   
   if (N == 0 || isNaN(N))
   {
      return "00";
   }
   
   N = Math.max(0,N); 
   N = Math.min(N,255); 
   N = Math.round(N);
   
   return "0123456789ABCDEF".charAt((N-N%16)/16) + "0123456789ABCDEF".charAt(N%16);
}

function getDropDownValue(obj)
{
   var ret = "";
   var realObj = getObject(obj);
   if (realObj)
   {
      try
      {
         ret = realObj.options[realObj.selectedIndex].value;
      }
      catch(e)
      {
      }
   }
   
   return ret;
}

//makes an element visible
function show(obj)
{
   var realObj = getObject(obj);
   if (realObj)
   {
      realObj.style.visibility = "visible";
   }
}

//hides an element
function hide(obj)
{
   var realObj = getObject(obj);
   if (realObj)
   {
      realObj.style.visibility = "hidden";
   }
}

//toggles visibility of an element
function toggleVisibility(obj)
{
   var realObj = getObject(obj);
   if (realObj != null && realObj.style)
   {
      if (isVisible(realObj))
      {
         hide(realObj);
      }
      else
      {
         show(realObj);
      }
   }
}

function toggleDisplay(obj)
{
   var realObj = getObject(obj);
   
   if (realObj != null && realObj.style)
   {
      if (realObj.style.display == "none")
      {
         realObj.style.display = "block";
      }
      else
      {
         realObj.style.display = "none";
      }
   }
}

//is an element visible?
function isVisible(obj)
{
   var realObj = getObject(obj);
   if (realObj)
   {
      return realObj.style.visibility == "visible";
   }
   return false;
}

//set focus to an element
function setFocusToElement(obj)
{
   var realObj = getObject(obj);
   if (realObj != null && realObj.focus)
   {
      realObj.focus();
      if (realObj.select)
      {
         realObj.select();
      }
   }
}


//Add the 'trim' function to String.
String.prototype.trim = function() 
{
  return( this.replace(/^\s*([\s\S]*\S+)\s*$|^\s*$/,'$1') ); 
}

//*************************
//Validation Methods
//*************************
function isNumeric(str)
{
   str = str.trim();
   var num = parseInt(str);
   if (num == NaN)
   {
      return false;
   }
   else
   {
      //check and see if our string rep of the number matches the string
      //i.e. 128px will be turned into 128, so we need to check length so 
      //we know if something was stripped off or not
      var numStr = new String(num);
      if (numStr.length == str.length)
      {
         return true;
      }
   }
   
   return false;
}

//*************************
//Positioning Methods
//*************************
//Move an object to a specific location in pixel coordinates
function shiftTo(obj, x, y)
{
   var realObj = getObject(obj);
   if (realObj)
   {
      //equalize incorrect numeric value type
      var units = (typeof realObj.style.left == "string") ? "px" : 0;
      realObj.style.left = x + units;
      realObj.style.top = y + units;
   }
}

function setZIndex(obj, zOrder)
{
   var realObj = getObject(obj);
   if (realObj)
   {
      realObj.style.zIndex = zOrder;
   }
}

//***********************************
//Event Methods
//***********************************
//Attaches an event hander to a specific node, event name must be passed in without the 'on' prefix.
function attachEventHandler(node, baseEventName, eventHandlerFunctionReference)
{
   if (node.attachEvent)
   {
      //IE way
      node.attachEvent("on" + baseEventName, eventHandlerFunctionReference);
   }
   else
   {
      //Gecko way
      node.addEventListener(baseEventName, eventHandlerFunctionReference, true);
   }
}

//IE uses a different event model than W3C, use this function to get the real event.
function getEvent(evt)
{
   return (evt) ? evt : ((event) ? event : null);
}

//Gets the element that was the source of the event.
function getEventSource(evt)
{
   var elem = null;
   evt = getEvent(evt);
   if (evt)
   {
      if (evt.target)
      {
         elem = evt.target;
      }
      else if (evt.srcElement) //IE
      {
         elem = evt.srcElement;
      }
   }
   
   return elem;
}

//returns the X coordinate of the mouse event
function getEventMouseX(evt)
{
   evt = getEvent(evt);
   if (evt.pageX) return evt.pageX;
   else if (evt.clientX) return evt.clientX;
}

//Inspects the passed in event, sees if it is for the indicated element or it's children.
function isEventForElementOrChildren(elementID, e)
{
   var ret = false;
   e = getEvent(e);
   var elem = getObject(elementID);
   if(elem)
   {
      var target = getEventSource(e);      

      //First, check self
      if(target == elem)
      {
         ret = true;
      }
      else
      {
         //Next, check parents.
         var parent = target.parentNode;
         while(parent != null && parent != document)
         {

            if(parent == elem)
            {
               ret = true;
               break;
            }

            parent = parent.parentNode
         }
      }
   }
   return ret;
}

/*
   Document Click handling
*/
var g_arrClickEventListeners = new Array();
//Registers a listener, allowing us to supply the 'this' reference to use when calling function on event.
function registerDocumentClickEventListener(thisRef, funcListener, key)
{
   if (g_arrClickEventListeners.length == 0)
   {
      //handle document level click events to know when to hide dropdown.
      attachEventHandler(document, 'click', handleDocumentClick);
   }

   var elem = new Object();
   elem.thisRef = thisRef;
   elem.key = key;
   elem.func = funcListener;
   
   if(key){
      //replace the registration if key is provided.
      var found = false;
      for(var i=0; i<g_arrClickEventListeners.length; i++){
         if(g_arrClickEventListeners[i].key == key) {
            found = true;
            g_arrClickEventListeners[i] = elem;
            break;
         }
      }
      
      if(!found)
         g_arrClickEventListeners[g_arrClickEventListeners.length] = elem;
   }
   else{ //just add it if no key provided.
      g_arrClickEventListeners[g_arrClickEventListeners.length] = elem;
   }
}

function handleDocumentClick(e)
{
   e = getEvent(e);
   for( var i=0; i < g_arrClickEventListeners.length; i++)
   {
      var cur = g_arrClickEventListeners[i];
      try
      {         
         cur.func.call(cur.thisRef, e);
      }
      catch(ex)
      {
     
      }
   }
   
   return true;
}

function getAbsoluteTop(elem)
{
   var ret = 0;
   if(elem)
   {
      var totalOffset = elem.offsetTop;
      var curNode = elem.offsetParent;
      while(curNode != null)
      {
         totalOffset += curNode.offsetTop;
         
         if(curNode == curNode.offsetParent)
         {
            break;
         }
            
         curNode = curNode.offsetParent;
         
      }
      ret = totalOffset;
   }
   return ret;
}
        
function getAbsoluteLeft(elem)
{
   var ret = 0;
   if(elem)
   {
      var totalOffset = elem.offsetLeft;
      var curNode = elem.offsetParent;
      while(curNode != null)
      {
         totalOffset += curNode.offsetLeft;
         
         if(curNode == curNode.offsetParent)
         {
            break;
         }
            
         curNode = curNode.offsetParent;
         
      }
      ret = totalOffset;
   }
   return ret;
}         

//returns the Y coordinate of the mouse event
function getEventMouseY(evt)
{
   evt = getEvent(evt);
   if (evt.pageY) return evt.pageY;
	else if (evt.clientY) return evt.clientY;
}

//Usage: 'INPUT id="file1" onkeypress="return killEnter(event);" ...
function killEnter(evt) 
{ 
   evt = getEvent(evt);
   if (evt.keyCode) return (evt.keyCode != 13); 
   if (evt.which) return (evt.which != 13); 
   return true; 
}

//Generic event routing..
var CentricsEventRouter = {
   Events : new Array(),
   
   //Register an event for callback
   //can pass a function or a hunk of JS
   //function will be passed: eventName, & optionally an arguments object.
   Listen: function(eventName, func) {
      if(this.Events[eventName] == null)
      {
         this.Events[eventName] = new Array();
      }
      this.Events[eventName].push(func);
   },
   
   //Fires the event notification
   Fire : function(eventName, args) {
      if(this.Events[eventName] != null)
      {
         var i;
         for(i=0; i< this.Events[eventName].length; i++)
         {
            var func = this.Events[eventName][i];
            
            if(func)
            {
               if(typeof(func) == "function")
               {
                  func(eventName, args);
               }
               else
               {                        
                  //Try to eval it as a javascript string.
                  eval(func);
               }
            }
         }
      }
   }
};

// Function to match the heights of DIVs
function MatchDIVHeights(divs)
{
   var maxHeight = 0;
   
   // Find the maximum height
   for (var i = 0; i < divs.length; i++)
   {
      if(divs[i]) {      
         if (divs[i].offsetHeight)
         {
            maxHeight = Math.max(maxHeight, divs[i].offsetHeight);
         }
         else if (divs[i].style.pixelHeight)
         {
            maxHeight = Math.max(maxHeight, divs[i].style.pixelHeight);
         }
      }
   }
   
   // Assign the maximum height
   for (var i = 0; i < divs.length; i++)
   {
      if(divs[i]) {
         divs[i].style.height = maxHeight + "px";
      }
   }
}

// Function to force the maximum width of an image so it doesn't break the layout of the page
function ForceImageMaxWidth(imageClientID) 
{
   var imageControl = $get(imageClientID);

   if (imageControl != null) 
   {
      var maxWidth = getStyle(imageControl.parentNode, "width").replace("px", "");
      var width = imageControl.width;
      var height = imageControl.height;

      if (width > maxWidth) 
      {
         var f = 1 - ((width - maxWidth) / width);
         imageControl.width = width * f;
         imageControl.height = height * f;
      }
   }
}
