
// The list of common JS Routines that can be systematize and usfule in any project (not PAT only).
// Can be changed and extend.

//-------------------------------------------------- Key Code Constants --------------------------------------------------

var ESC_KEY_CODE = 27;
var ENTER_KEY_CODE = 13
var TAB_KEY_CODE = 9;

var LEFT_KEY_CODE = 37;
var RIGHT_KEY_CODE = 39;
var TOP_KEY_CODE = 38;
var BOTTOM_KEY_CODE = 40;

var DEL_KEY_CODE = 46;
var BSP_KEY_CODE = 8;

var	ie=document.all;


    // Should be modify to support other browsers
    function Browser () 
    {
        switch(navigator.appName)
        {
            case "Microsoft Internet Explorer":
                return "ie";
            case "Netscape":
                return "ff";
        }
      return null;
    }

//------------------------------------------------ Cookie Handling Routines ------------------------------------------------

    function testSessCookie () 
    {
      document.cookie ="testSessionCookie=Enabled";
      if (getCookieValue ("testSessionCookie")=="Enabled") return true;
      return false;
    }

    function testPersCookie () 
    {
      setPersCookie ("testPersistentCookie", "Enabled", "minutes", 1);
      if (getCookieValue ("testPersistentCookie")=="Enabled") return true;  
      return false;
    }

    function setSessCookie (cookieName, cookieValue) 
    {
      if (testSessCookie()) {
        document.cookie = escape(cookieName) + "=" + escape(cookieValue) + "; path=/";
        return true;
      }
      return false;
    }

    function getCookieValue (cookieName) 
    {
      var exp = new RegExp (escape(cookieName) + "=([^;]+)");
      if (exp.test (document.cookie + ";")) {
        exp.exec (document.cookie + ";");
        return unescape(RegExp.$1);
      }
      return null;
    }

    function setPersCookie (CookieName, CookieValue, periodType, offset) 
    {
      var expireDate = new Date ();
      offset = offset / 1;
      
      var myPeriodType = periodType;
      switch (myPeriodType.toLowerCase()) {
        case "years": 
         var year = expireDate.getYear(); // Note some browsers give only the years since 1900, and some since 0.
         if (year < 1000) year = year + 1900;     
         expireDate.setYear(year + offset);
         break;
        case "months": expireDate.setMonth(expireDate.getMonth() + offset); break;
        case "days": expireDate.setDate(expireDate.getDate() + offset); break;
        case "hours": expireDate.setHours(expireDate.getHours() + offset); break;
        case "minutes": expireDate.setMinutes(expireDate.getMinutes() + offset); break;
        default: alert ("Invalid periodType parameter for setPersCookie()"); break;
      } 
      
      document.cookie = escape(CookieName ) + "=" + escape(CookieValue) + "; expires=" + expireDate.toGMTString() + "; path=/";
    }  

    function deleteCookie (cookieName) 
    {
      if (getCookieValue (cookieName)) setPersCookie (cookieName,"Pending delete","years", -1);  
      return true;     
    }


//----------------------------------------------------- Event Handling Routines -----------------------------------------------------

    function RmvHandler(object, event, handler) 
    {
        if(object == null) return;
        for(var i=0; handler.Hndls && i<handler.Hndls.length; i++)
            if(handler.Hndls[i].obj == object && handler.Hndls[i].evt == event)
                { var h = handler.Hndls[i].Fnct; handler.Hndls = handler.Hndls.slice(0,i).concat( handler.Hndls.slice(i+1) ); handler = h; break; }
        
        if (object.removeEventListener) object.removeEventListener(event, handler, false); 
        else if (object.detachEvent) object.detachEvent('on' + event, handler); 
        else alert("Remove handler is not supported"); 
    }

    function AddHandler(object, event, handler, useCapture) 
    { 
        if(object == null) return;

        RmvHandler(object, event, handler);
        var hndl = new evtHndl(object, handler, event);

        if (object.addEventListener) object.addEventListener(event, hndl.Fnct, useCapture ? useCapture : false); 
        else if (object.attachEvent) object.attachEvent('on' + event, hndl.Fnct); 
        else alert("Add handler is not supported"); 
    } 

    function evtHndl(obj, hnd, evt)
    {
        var self = this;

        self.obj = obj;
        self.hnd = hnd;
        self.evt = evt;

        if(!hnd.Hndls) hnd.Hndls = new Array();
        hnd.Hndls.push(self);

        self.Fnct = function (evt)
            {
                self.hnd(self.obj, evt);
            }
    }

    function CancelBubbling(evt) 
    { 
        (evt || window.event).cancelBubble = true; 
    }


    function getEventtSrc(evt)
    {
	    var evt = evt || window.event;
	    return evt.this_ || evt.target || evt.srcElement;
    }

//---------------------------- PopUp Routines (to show some absolute position divs as popup) ----------------------------------------
//-------------- Support only one PopUp opened (can be easily changed if exclude hiding "problem" elements) -------------------------

    var popupList = new Object(); //to hide on document event


    function HidePopUp(obj)
    {
        obj.style.display = "none";
        if(obj.id && popupList[obj.id]) delete popupList[obj.id];
	    showElements();
    }


    function HidePopUps()
    {
        for (var p in popupList) HidePopUp(popupList[p]);
    }


    function ShowPopUp(obj, org)
    {
        HidePopUps();
        
	    SetDropDownPos(org, obj);
	    obj.style.display = "";
        popupList[obj.id] = obj;

        hideElements(obj);
    }

    AddHandler(document, "click", HidePopUps);
    AddHandler(document, "keypress", HidePopUps);

//-------------------------- PopUp dives position (to keep it in the visible area) -------------------------------------

    function SetDropDownPos(button, drdown)
    {
        var rect = GetRect(button);

        var x=rect.x;
        var y=rect.y + rect.Height + 1;
        
        var body = GetBodySize();

        if (y + drdown.offsetHeight > body.Height)
        {
            y = body.Height - drdown.offsetHeight;
            if (y < 0) y = 0;
        }

        if (x + drdown.offsetWidth > body.Width)
        {
            x = body.Width - drdown.offsetWidth;
            if (x < 0) x = 0;
        }

        drdown.style.left = x + "px";
        drdown.style.top  = y + "px";
    }


    function GetBodySize()
    {
        var doc = (document.compatMode && document.compatMode=="CSS1Compat") ? document.documentElement : document.body;
        return {Height:doc.clientHeight + doc.scrollTop - 6, Width:doc.clientWidth + doc.scrollLeft - 6};
    }


    function GetRect(el)
    {
        var res = {x:0, y:0, Width:el.offsetWidth, Height:el.offsetHeight};
		
		var box = getCoords(el);
        res.x = box.x;
        res.y = box.y - 2;

        return res;
    }


    function getCoords (el) 
    {
        var coords = { x: 0, y: 0, width: el.offsetWidth, height:el.offsetHeight };
        while (el) 
        {
            coords.x += el.offsetLeft;
            coords.y += el.offsetTop;
            el = el.offsetParent;
        }
        return coords;
    }
    
//-------------------------- Hidding "problem" elements under pop up div -------------------------------------

	var HiddenFields = new Array()


    /* unhides <select> and <applet> objects (for IE only) */
    function showElements( )
    {
        for( i = 0; i < HiddenFields.length; i++ )
          obj = HiddenFields[i].style.visibility = "visible";
    }


    /* hides <select> and <applet> objects (for IE only) */
    function hideElements( overDiv )
    {
	    hideElement( 'SELECT', overDiv );
	    hideElement( 'APPLET', overDiv );			
	}


    /* hides "elmID" under "overDiv" objects (for IE only) */
    function hideElement( elmID, overDiv )
    {
        if( !ie ) return;
    
        for( i = 0; i < document.all.tags( elmID ).length; i++ )
        {
          obj = document.all.tags( elmID )[i];
          if( !obj || !obj.offsetParent ) continue;
      
          // Find the element's offsetTop and offsetLeft relative to the BODY tag.
          objLeft   = obj.offsetLeft;
          objTop    = obj.offsetTop;
          objParent = obj.offsetParent;
          
          while((objParent.tagName.toUpperCase() != "BODY") && (objParent.tagName.toUpperCase() != "HTML"))
          {
            objLeft  += objParent.offsetLeft;
            objTop   += objParent.offsetTop;
            objParent = objParent.offsetParent;
          }
      
          objHeight = obj.offsetHeight;
          objWidth = obj.offsetWidth;

          if(overDiv.offsetLeft + overDiv.offsetWidth > objLeft && overDiv.offsetTop + overDiv.offsetHeight > objTop &&
             overDiv.offsetTop  < objTop + objHeight && overDiv.offsetLeft < objLeft + objWidth)
          {
            obj.style.visibility = "hidden";
            HiddenFields.push(obj);
          }
        }
    }


//------------------------------------------------ Hash Object Routines ------------------------------------------------

    function Hash()
    {
        var hash = new Object();

        for(var i=0; i<arguments.length; )
            hash[arguments[i++]] = arguments[i++];

        return hash;
    }

    function AddHash(hash)
    {
        if(hash == null) hash = new Object();

        if(arguments.length == 2)
            for (var prop in arguments[1])
                hash[prop] = arguments[1][prop];
        else
            for(var i=1; i<arguments.length; )
                hash[arguments[i++]] = arguments[i++];

        return hash;
    }

    function CloneHash(hash)
    {
	    var newHash = new Object();
	    for (var key in hash)
		    newHash[key] = hash[key];
	    return newHash;
    }


//------------------------------------------------ Data Validation Routines ------------------------------------------------

    function ValidateEMail(val)
    {
        var rex = new RegExp("^([-_.!#\\$%&a-z0-9])+@([-_!#\\$%&a-z0-9]+\\.)+[a-z]{2,4}$", "i");
        return val == "" || rex.test(val);
    }

    function ValidateRequired(val)
    {
        var rex = new RegExp("^\\s*$");
        return (val != null && !rex.test(val));
    }

    function ValidateInt(val)
    {
        if(val == "") return true;
       res = new RegExp("^[0-9]+$");
       return (val != null && res.test(val));
    }

    function ValidateFloat(val)
    {
    	res = new RegExp("^[0-9]*\.?[0-9]*$");
		return val=="" || res.test(val);
    }
//-------------------------------------------------- Set Text Not As HTML -------------------------------------------------------------
function SetText(elem,text)
{
   if(typeof(elem.innerText) != 'undefined')
      elem.innerText = text;
   else
      elem.textContent = text;
}

function txt2js(txt) 
{
    return txt.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"").replace(/\'/g, "\\\'").replace(/\n/g, "\\n").replace(/\r/g, "");
}



//-------------------------------------------------- Imput cursor position -------------------------------------------------------------
function getSelectionStart(o) {
	if (o.createTextRange) {
		var r = document.selection.createRange().duplicate()
		r.moveEnd('character', o.value.length)
		if (r.text == '') return o.value.length
		return o.value.lastIndexOf(r.text)
	} else return o.selectionStart
}

function getSelectionEnd(o) {
	if (o.createTextRange) {
		var r = document.selection.createRange().duplicate()
		r.moveStart('character', -o.value.length)
		return r.text.length
	} else return o.selectionEnd
}




//------------------------------------------------ Money Format Routines ------------------------------------------------
function FormatMoney(val)
{
    if(val == null || val == "null") val = "";
    val = "" + val;
    
    if(val.indexOf(".") == -1) val += ".00";
    var p = val.indexOf(".");
    
    var s1 = val.substring(0, p);
    var s2 = val.substring(p + 1);
    
    if(s1.length == 0) s1 = "0";
    if(s2.length == 0) s2 = "00";
    if(s2.length == 1) s2 += "0";
    if(s2.length > 2) s2 = s2.substring(0, 2);
    
    return s1 + "." + s2;
}

function ImpEventMoneyFormatCheck(imp, e)
{
    var p = getSelectionStart(imp);
    if((e.keyCode < 48 || e.keyCode > 57) && e.keyCode != 189 && e.keyCode != 190 && e.keyCode != ESC_KEY_CODE && e.keyCode != ENTER_KEY_CODE && e.keyCode != TAB_KEY_CODE && e.keyCode != LEFT_KEY_CODE && e.keyCode != RIGHT_KEY_CODE && e.keyCode != TOP_KEY_CODE && e.keyCode != BOTTOM_KEY_CODE && e.keyCode != DEL_KEY_CODE && e.keyCode != BSP_KEY_CODE)
    {
        e.cancelBubble = true; 
        return false;
    }
    if((e.keyCode >= 48 && e.keyCode <= 57) || e.keyCode == 190 || e.keyCode == 189)
    {
        var ch = (e.keyCode == 190 ? "." : e.keyCode == 189 ? "-" : String.fromCharCode(e.keyCode));
        var newval = imp.value.substring(0, p) + ch + imp.value.substring(p);
        if(!/^\-?(\d)*\.?(\d){0,2}$/.test(newval))
        {
            e.cancelBubble = true; 
            return false;
        }
    }
    return true;
}
