/*
Author/Owner: 	Daniel Peel.
Contact: 		mintpants@tiscali.co.uk.
Details: 		Base JavaScript.
Created:		01.06.07
Updated: 		13.11.07 - Added getSelText Function
Added swapclass function
Renamed elButtonise functions to elButtonisHover and elButtoniseHoverUndo
01.12.07 - deleted elButtonisHover and elButtoniseHoverUndo (swapClass confortably does the same task)
17.01.08 - Added rightClick function
19.01.08 - Moved the div explode function to its own script
25.01.08 - Added the elCollapse function which collapses or expands an element.
14.02.08 - Started the augment textarea rows class
05.03.08 - added PHP function emulations isset, in_array.
added simplifying functions return object and is_obj
05.03.09 - Begun integration with the NET library
05.03.09 - Changed $ to ById to avoid conflicts with prototype based libraries
16.03.09 - Added ToggleFormFieldValue method
16.04.09 - Added GetObj Method to quickly return an object from id or object
11.05.09 - Added ReadCookie, SetCookie Methods
20.06.09 - Updated/Improved the IsSet function, threw an error if the passed var was null, so added or null and checked that first to exit the function
*/
//*********************************************************************************************//
//						            Air NameSpace
//*********************************************************************************************//
Air = {}
//*********************************************************************************************//
//						            Capture Global Object
//*********************************************************************************************//
Air.Global = this;
//*********************************************************************************************//
//						            CORE javascript functions
//*********************************************************************************************//

function ById(id) { return (document.getElementById(id)); }
function IsSet(v) { return ((v == null || typeof (v) == 'undefined' || v.length == 0) ? false : true); }
function Empty(v) { return ((v.length == 0) ? false : true); }
function IsObj(v) { return ((typeof (v) == 'object') ? true : false); }
function InArray(array, value) { for (var i in array) if (array[i] == value) return true; }
function GetObj(el) { if (!IsObj(el)) { return ById(el); } else { return el; } }
//************************************* Augment Arguments ************************************//
function Augment(oSelf, oOther) {
    if (oSelf == null) {
        oSelf = {};
    }
    for (var i = 1; i < arguments.length; i++) {
        var o = arguments[i];
        if (typeof (o) != 'undefined' && o != null) {
            for (var j in o) {
                oSelf[j] = o[j];
            }
        }
    }
    return oSelf;
}
//*************************************************************************************************************//
//Required Methods * Required Methods * Required Methods * Required Methods * Required Methods * Required Methods
//*************************************************************************************************************//
//fetch inner window size
var innerWin = new Object();
function innerWindowSize() {
    if (typeof (window.innerWidth) == 'number') {
        //Non-IE
        innerWin.Width = window.innerWidth;
        innerWin.Height = window.innerHeight;
    }
    else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        innerWin.Width = document.documentElement.clientWidth;
        innerWin.Height = document.documentElement.clientHeight;
    }
    else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        innerWin.Width = document.body.clientWidth;
        innerWin.Height = document.body.clientHeight;
    }
}

//get the scrolled position
function scrolled() {
    var iebody = (document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
    innerWin.scrollX = document.all ? iebody.scrollLeft : pageXOffset;
    innerWin.scrollY = document.all ? iebody.scrollTop : pageYOffset;
}

//find the center of the screen relative to the size of the div to be positioned
function divScreenCenter(width, height) {
    //init the inner window size object
    innerWindowSize();
    scrolled();

    //determine the window center		
    var horCent = Math.floor((innerWin.Width / 2) - (width / 2));
    var verCent = (Math.floor((innerWin.Height / 2) - (height / 2))) + innerWin.scrollY;

    //make sure the pop doesnt fall off the screen
    if (horCent < 0) {
        horCent = 0;
    }

    //make sure the pop doesnt fall off the screen
    if (verCent < 0) {
        verCent = 0;
    }

    return { verCent: verCent, horCent: horCent };
}
//Get the complete body size
function docSize() {
    var b = document.body, e = document.documentElement;
    var esw = 0, eow = 0, bsw = 0, bow = 0, esh = 0, eoh = 0, bsh = 0, boh = 0;
    if (e) {
        esw = e.scrollWidth;
        eow = e.offsetWidth;
        esh = e.scrollHeight;
        eoh = e.offsetHeight;
    }
    if (b) {
        bsw = b.scrollWidth;
        bow = b.offsetWidth;
        bsh = b.scrollHeight;
        boh = b.offsetHeight;
    }
    return { w: Math.max(esw, eow, bsw, bow), h: Math.max(esh, eoh, bsh, boh) };
}
//***************** finds position of any element ****************//
// N.B firefox doesnt allow an entire div or table to be linked it 
// will close the link before the table so requestlink is funny
//****************************************************************//
function findPosition(element) {

    if (typeof element != "object") {
        var element = document.getElementById(element);
    }

    //if the element has any parents
    if (element.offsetParent) {
        /*runs through all the parent nodes adding each realtive offset dimensions 
        to get the elements offset from the top parent node*/
        for (var posX = 0, posY = 0; element; element = element.offsetParent) {
            posX += element.offsetLeft;
            posY += element.offsetTop;
            //N.B ie and mozilla have different numbers of parents	 
        }

        return [posX, posY];
    }
    else //element has no parents
    {
        return [element.x, element.y];
    }
}
//**************************** New Design Pattern ***********************/

function MousePosition(event) {

    if (window.event) {
        return { x: window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft,
            y: window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop
        }
    }
    else {
        return { x: event.clientX + window.scrollX,
            y: event.clientY + window.scrollY
        }
    }
}

function InsideBounds(event, target) {

    var target = GetObj(target);
    var coOrds = findPosition(target);

    //X
    if ((MousePosition(event).x > coOrds[0]) && (MousePosition(event).x < (coOrds[0] + target.offsetWidth))) {
        //Y
        if ((MousePosition(event).y > coOrds[1]) && (MousePosition(event).y < (coOrds[1] + target.offsetHeight))) {
            return true;
        }
    }

    return false;
}

//*************************************************************************************************************//
//Required Methods * Required Methods * Required Methods * Required Methods * Required Methods * Required Methods
//*************************************************************************************************************//
function SetCookie(_string, clear) {
    //Creates Cookie in  key=value& format
    try {
        if (clear == true) { //if clear is true we clear previously set cookies
            document.cookie = _string + "&";
        }
        else {
            document.cookie += _string + "&"; //append to cookies
        }
    }
    catch (Error) {

        return false;
    }

    if (document.cookie.length > 0) {
        return true;
    }
    else {
        return false;
    }
}

function ReadCookie(key) {

    if (document.cookie.length > 0) {

        var _valueStart = document.cookie.indexOf(key + "=");

        if (_valueStart != -1) {

            _valueStart = key.length + 1;

            var _value_end = document.cookie.lastIndexOf("&");

            if (_value_end != -1) {
                return unescape(document.cookie.substring(_valueStart, _value_end));
            }
            else {
                return null;
            }
        }
        else {
            return null;
        }
    }
}

function KVPStringToArray(text) {

    var responseArray = new Array();
    if (text.length > 0) {

        var firstIndex = text.indexOf("=");

        if (firstIndex != -1) {

            for (var _i = 0; _i < text.length; _i++) {

                //build the array pair
                var _key = text.substring(_i, text.indexOf("=", _i));

                if (text.indexOf("&", _i) == -1) {//last one
                    var _value = text.substring((text.indexOf("=", _i) + 1), text.length);
                }
                else {
                    var _value = text.substring((text.indexOf("=", _i) + 1), text.indexOf("&", _i));
                }

                responseArray[_key] = unescape(_value);

                //reset _i
                _i = text.indexOf("&", _i);
                if (_i == -1) {
                    break;
                }
            }
        }
        else {
            return false;
        }
    }
    else {
        return false;
    }

    return responseArray;
}

function QueryString() {
    return KVPStringToArray(window.location.search.substring(1));
}

function GetSelectedText() {

    var txt;

    if (window.getSelection) {
        txt = window.getSelection();
    }
    else if (document.getSelection) {
        txt = document.getSelection();
    }
    else if (document.selection) {
        //txt = document.selection.createRange().text;	
        txt = document.selection.createRange().duplicate().text;
    }
    return txt;
}

function ToggleCssDisplay(el) {

    var oEl;

    if (!IsObj(el)) {
        oEl = ById(el);
    }
    else {
        oEl = el;
    }

    if (oEl.style.display == "none") {
        oEl.style.display = "block";
        return;
    }
    else {
        oEl.style.display = "none";
        return;
    }
}
function ToggleCssVisibility(el) {

    var oEl;

    if (!IsObj(el)) {
        oEl = ById(el);
    }
    else {
        oEl = el;
    }

    if (oEl.style.visibility == "hidden") {
        oEl.style.visibility = "visible";
        return;
    }
    else {
        oEl.style.visibility = "hidden";
        return;
    }
}

function SwapClass(el, classOff, classOn) {

    var oEl;

    if (!IsObj(el)) {
        oEl = ById(el);
    }
    else {
        oEl = el;
    }

    if (oEl.className == classOff) {
        oEl.className = classOn;
    }
    else if (oEl.className == classOn) {
        oEl.className = classOff;
    }
}

function GetOpacity(el) {

    var elObj = GetObj(el);

    if (isNaN(elObj.style.opacity)) {
        return parseFloat(elObj.style.filter);
    }
    else {
        return elObj.style.opacity * 100;
    }
}

function RemoveSelectors(_selectorString) {

    if (_selectorString.indexOf(".", 0) != -1) {
        return _selectorString.substr(_selectorString.indexOf(".", 0) + 1);
    }
    else if (_selectorString.indexOf("#", 0) != -1) {
        return _selectorString.substr(_selectorString.indexOf("#", 0) + 1);
    }
    else if (_selectorString.indexOf(">", 0) != -1) {
        return _selectorString.substr(_selectorString.indexOf(">", 0) + 1);
    }
    else if (_selectorString.indexOf(" ", 0) != -1) {
        return _selectorString.substr(_selectorString.indexOf(" ", 0) + 1);
    }
    else {
        return _selectorString;
    }
}

function GetCSSRule(ruleName, deleteFlag) {
    // Convert test string to lower case.
    ruleName = ruleName.toLowerCase();

    // If browser can play with stylesheets
    if (document.styleSheets) {
        // For each stylesheet
        for (var i = 0; i < document.styleSheets.length; i++) {
            // Get the current Stylesheet
            var styleSheet = document.styleSheets[i];
            // Initialize subCounter.
            var ii = 0;
            // Initialize cssRule.
            var cssRule = false;
            // For each rule in stylesheet
            do {
                // Browser uses cssRules?
                if (styleSheet.cssRules) {
                    // Yes --Mozilla Style                
                    cssRule = styleSheet.cssRules[ii];
                } else {
                    // Browser usses rules?    
                    // Yes IE style.                              
                    cssRule = styleSheet.rules[ii];
                }
                if (cssRule) {

                    var _tempCssRule = RemoveSelectors(cssRule.selectorText.toLowerCase());

                    if (_tempCssRule == ruleName) {

                        return cssRule;
                    }
                }
                ii++;
            } while (cssRule)
        }
    }
    return false;
}

function GetParentNode(startNode, nodeName) {

    var startNode = GetObj(startNode).parentNode;
    if (IsSet(startNode)) {
        if (startNode.nodeName.toLowerCase() == nodeName)
            return startNode;
        else
            GetParentNode(startNode, nodeName);
    }

    else {
        return null;
    }
}

function GetScript(content) {
    var posStart, posEnd;
    posStart = content.search(/\<script\>/i);
    if (posStart == -1) {
        return null;
    }
    else {
        posEnd = content.search(/\<\/script>/i);

        if (posEnd == -1) {
            return null;
        }
        else {
            return content.substring((posStart + 8), posEnd);
        }
    }
}
//Evals code into the global scope
function Eval(code) {
    if (window.execScript) {
        window.execScript(code);
        return null; // execScript doesn’t return anything
    }
    return Air.Global.eval ? Air.Global.eval(code) : eval(loadedScript);
}

Air.FX = {
    Expand: function(target) {

        var i = 0;
        var cycles = 6;
        var pxPerCycleOffset = 0;
        var target = GetObj(target);
        target.style.overflow = 'hidden';
        target.style.opacity = ".4";
        target.style.filter = "alpha(opacity=40)";
        
        //allows expanding on top of an existing height
        if (!IsSet(target.style.height)) {
            target.style.height = "0px";
        }
        else { // if the panel is already open account for this height
            pxPerCycleOffset = parseFloat(target.style.height, 10) / cycles;
        }

        var targetsHeight = target.scrollHeight;
        var pxPCycle = targetsHeight / cycles;

        var tick = setInterval(function() {

        if (i == cycles) {
            target.style.opacity = "1";
            target.style.filter = "alpha(opacity=100)";
                clearInterval(tick);
                return;
            }

            target.style.height = (parseFloat(target.style.height, 10) + pxPCycle) - pxPerCycleOffset + "px";
            i++;

        }, 20);
    },
    Collapse: function(target, collapseTo) {

        var i = 0;
        var target = GetObj(target);
        var targetsHeight;
        target.style.overflow = 'hidden';
        target.style.opacity = ".4";
        target.style.filter = "alpha(opacity=40)";
        
        if (collapseTo)
            targetsHeight = target.scrollHeight - collapseTo;
        else
            targetsHeight = target.scrollHeight;

        var pxPCycle = targetsHeight / 6;
        var newHeight;

        var tick = setInterval(function() {

        if (i == 6) {
            target.style.opacity = "1";
            target.style.filter = "alpha(opacity=100)";
                clearInterval(tick);
                return;
            }

            newHeight = parseFloat(target.style.height, 10) - pxPCycle;

            if (newHeight < 0) {
                newHeight = 0;
            }

            target.style.height = newHeight + "px";
            i++;

        }, 20);
    }
};