/*
BUILD: v2.0, 08.06.2009, Sergej Škaro
Copyright (c) 2009 by Binom.

All rights are reserved. Reproduction or transmission in whole or in part, in
any form or by any means, electronic, mechanical or otherwise, is prohibited
without the prior written consent of the copyright owner.

NOTE:
- Function parameters with prefix $ in name are required parameters.
- Functions can be called with Binom.Utils.NameOfFunction(params) within HTML
- New namespaces can be created using namespace constructor Namespace.New("Namespace.Path")
*/

/// Namespace constructor (global Object cointainers)
if (typeof Namespace == "undefined") var Namespace = {}; // Manualy creating namespace

/// Create any namespace
Namespace.New = function ($namespace) {
    try {
        if ($namespace != null && $namespace.length > 0) {
            $namespace = $namespace.split('.');
            var objParent = window;
            for (var i = 0; i < $namespace.length; i++) {
                var currentNamespace = $namespace[i];
                if (!objParent[currentNamespace]) objParent[currentNamespace] = {};
                objParent = objParent[currentNamespace];
            }
        }
    }
    catch (e) { alert("Namespace.New Error!"); }
};

// Define namespaces
Namespace.New("Binom.Utils"); // Creating namespace using namespace constructor
// Create shortcut
var $BUtl = Binom.Utils;

/// Alert user with message and optional error details
Binom.Utils.NotifyUser = function ($msg, errObj, arrParams) {
    //try
    {
        if ($msg == null) $msg = "";
        if (arrParams != null) $msg += "\r\nparams: " + arrParams.toString();
        if (errObj != null) {
            $msg += "\r\n";
            if (errObj.number != null) $msg += "\r\nErrId: " + errObj.number;
            if (errObj.lineNumber != null) $msg += "\r\nErrLine: " + errObj.lineNumber;
            if (errObj.description != null) $msg += "\r\nErrDesc: " + errObj.description;
            if (errObj.message != errObj.description) $msg += "\r\nErrMsg: " + errObj.message
        }
        if ($msg.length > 0) alert($msg); // Reporting message
    }
    //catch(e) { alert(" NotifyUser Error!" + $msg); }
};
/// Check if object is null, undefined or empty
Binom.Utils.IsNullOrEmpty = function ($content) {
    var emptyOrNull = true;
    try {
        emptyOrNull = this.ObjIsNull($content);
        if ((typeof $content == "string" || typeof $content == "array") && $content.length == 0) emptyOrNull = true;
    }
    catch (errObj) { this.NotifyUser("IsNullOrEmpty Error!", errObj, this.GetArguments(arguments)); }
    return emptyOrNull;
};
/// Check if object is null or undefined
Binom.Utils.ObjIsNull = function ($content) {
    var objectIsNull = true;
    try {
        if ($content != null && $content !== undefined && typeof $content != "undefined" && typeof $content != "unknown") objectIsNull = false;
    }
    catch (errObj) { this.NotifyUser("ObjIsNull Error!", errObj, this.GetArguments(arguments)); }
    return objectIsNull;
};
/// Dinamically reformat any function arguments for usage in notification
Binom.Utils.GetArguments = function ($collArgs) {
    var args = "";
    try {
        for (var i = 0; i < $collArgs.length; i++) {
            if (args.length > 0) args += ", ";
            var currentArg = $collArgs[i];
            switch (typeof currentArg) {
                case "string":
                    currentArg = "\"" + currentArg + "\"";
                    break;
                case "object":
                    if (currentArg != null && currentArg.id != null && currentArg.id.length > 0) currentArg = currentArg + "[id=\"" + currentArg.id + "\"]";
                    break;
                case "number":
                    currentArg = currentArg.toString();
                    break;
                case "array":
                    currentArg = "\"" + currentArg + "\"";
                    break;
                case "boolean":
                    currentArg = currentArg.toString();
                    break;
                default:
                    alert("New case for GetArguments: " + typeof currentArg);
                    break;
            }
            args += currentArg;
        }
    }
    catch (errObj) { this.NotifyUser("GetArguments Error!", errObj); }
    return args
};
/// Finds specified id in document body, returns refrence to object. Obsolite, use jquery instead!
Binom.Utils.GetObjById = function ($targetId) {
    var obj = null;
    try {
        if ($targetId != undefined && $targetId != null && $targetId.length > 0) obj = document.getElementById($targetId);
    }
    catch (errObj) { this.NotifyUser("GetObjById Error!", errObj, this.GetArguments(arguments)); }
    return obj;
};
/// Redirects user to specified uri
Binom.Utils.GetUrl = function ($uri) {
    try {
        if ($uri != null && $uri.length > 0) document.location = $uri;
    }
    catch (errObj) { this.NotifyUser("GetUrl Error!", errObj, this.GetArguments(arguments)); }
};
/// Creates flash object and embed tags, returns string
Binom.Utils.NewFlashTag = function ($src, w, h, transparent, bkg, tagId, ver, noScale, fullScr) {
    var tags = "";
    try {
        if (!this.IsNullOrEmpty($src)) {
            // Default values
            var defW = 0;
            var defH = 0;
            var defBkg = "000000";
            var defTransparent = false;
            var defTagId = "FlashObj" + (new Date()).getTime().toString(); // TagId unique default
            var defVer = 8;
            var defNoScale = false;
            var defFullScr = false;

            // Hardcoded parameters
            var pAlign = "middle";
            var pSAlign = "lt";
            var pAllowScriptAccess = "always";
            var pAllowNetworking = "all";
            var pMenu = false;
            var pQuality = "best";

            // Setting defaults if needed
            if (this.IsNullOrEmpty(w) || Number(w) == NaN || w < 0) w = defW;
            if (this.IsNullOrEmpty(h) || Number(h) == NaN || h < 0) h = defH;
            if (this.IsNullOrEmpty(bkg) || bkg.length <= 0) bkg = defBkg;
            if (this.IsNullOrEmpty(transparent)) transparent = defTransparent;
            if (this.IsNullOrEmpty(tagId) || tagId.length <= 0) tagId = defTagId;
            if (this.IsNullOrEmpty(ver) || Number(ver) == NaN || ver <= 0) ver = defVer;
            if (this.IsNullOrEmpty(noScale)) noScale = defNoScale;
            if (this.IsNullOrEmpty(fullScr)) fullScr = defFullScr;

            if (ver < 9 && fullScr == true) ver = 9;
            var fullVer = ver + ",0,0,0";
            if (ver == 9) fullVer = ver + ",0,45,0";

            // Building object tag
            tags = '<object';
            tags += ' classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
            tags += ' codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + fullVer + '"';
            tags += ' width="' + w + '"';
            tags += ' height="' + h + '"';
            tags += ' id="' + tagId + '"';
            tags += ' align="' + pAlign + '">';
            tags += '<param name="allowScriptAccess" value="' + pAllowScriptAccess + '" />';
            tags += '<param name="allowNetworking" value="' + pAllowNetworking + '" />';
            tags += '<param name="movie" value="' + $src + '" />';
            tags += '<param name="menu" value="' + pMenu.toString() + '" />';
            tags += '<param name="quality" value="' + pQuality + '" />';
            if (noScale == true) tags += '<param name="scale" value="noscale" />';
            tags += '<param name="salign" value="' + pSAlign + '" />';
            if (transparent == true) tags += '<param name="wmode" value="transparent" />';
            if (fullScr == true) tags += '<param name="allowFullScreen" value="true" />';
            tags += '<param name="bgcolor" value="#' + bkg + '" />';

            // Building embed tag
            tags += '<embed';
            tags += ' src="' + $src + '"';
            tags += ' menu="' + pMenu.toString() + '"';
            tags += ' quality="' + pQuality + '"';
            if (noScale == true) tags += ' scale="noscale"';
            tags += ' salign="' + pSAlign + '"';
            if (transparent == true) tags += ' wmode="transparent"';
            if (fullScr == true) tags += ' allowfullscreen="true"';
            tags += ' bgcolor="#' + bkg + '"';
            tags += ' width="' + w + '"';
            tags += ' height="' + h + '"';
            tags += ' name="' + tagId + '"';
            tags += ' align="' + pAlign + '"';
            tags += ' allowScriptAccess="' + pAllowScriptAccess + '"';
            tags += ' allowNetworking="' + pAllowNetworking + '"';
            tags += ' type="application/x-shockwave-flash"';
            tags += ' pluginspage="http://www.macromedia.com/go/getflashplayer" />';
            tags += '</object>';
        }
    }
    catch (errObj) { this.NotifyUser("NewFlashTag Error!", errObj, this.GetArguments(arguments)); }
    return tags;
};
/// Creates image tag, returns string
Binom.Utils.NewImgTag = function ($src, w, h, border, styleValue, cssClass, alt, otherParams, hrefUrl, hrefParams) {
    var tags = "";
    try {
        if (!this.IsNullOrEmpty($src)) {
            if (this.IsNullOrEmpty($alt)) alt = "";
            if (!this.IsNullOrEmpty(hrefUrl)) {
                tags = '<a href="' + hrefUrl + '"';
                if (!this.IsNullOrEmpty(hrefParams)) tags += ' ' + hrefParams;
                tags += '>';
            }
            tags += '<img';
            tags += ' src="' + $src + '"';
            if (!this.IsNullOrEmpty(w) && Number(w) > 0) tags += ' width="' + w + '"';
            if (!this.IsNullOrEmpty(h) && Number(h) > 0) tags += ' height="' + h + '"';
            if (!this.IsNullOrEmpty(border) && Number(border) >= 0) tags += ' border="' + border + '"';
            if (!this.IsNullOrEmpty(styleValue)) tags += ' style="' + styleValue + '"';
            if (!this.IsNullOrEmpty(cssClass)) tags += ' class="' + cssClass + '"';
            tags += ' alt="' + alt + '"';
            if (!this.IsNullOrEmpty(otherParams)) tags += otherParams;
            tags += '>';
            if (!this.IsNullOrEmpty(hrefUrl)) tags += '</a>';
        }
    }
    catch (errObj) { this.NotifyUser("NewImgTag Error!", errObj, this.GetArguments(arguments)); }
    return tags;
};
/// Changes image source, can be used for reloading image
Binom.Utils.SetImgSrc = function ($obj, $src, addTimestamp) {
    try {
        if (!this.IsNullOrEmpty($obj)) {
            var imgStamp = "";
            if (addTimestamp == true) imgStamp = "?uid=" + (new Date()).getTime().toString();
            $obj.attr("src", $src + imgStamp);
        }
    }
    catch (errObj) { this.NotifyUser("SetImgSrc Error!", errObj, this.GetArguments(arguments)); }
}
/// Sets class name for specified document object. Obsolite use jQuery instead!
Binom.Utils.SetCssClass = function ($obj, cssName) {
    try {
        if (!this.IsNullOrEmpty($obj)) {
            if (!this.IsNullOrEmpty(cssName)) {
                //$obj.addClass(cssName);
                $obj.className = cssName;
            }
            else {
                //$obj.removeClass();
            }
        }
    }
    catch (errObj) { this.NotifyUser("SetCssClass Error!", errObj, this.GetArguments(arguments)); }
};
/// Inserts html tags into specified document object innerHTML. Obsolite use jQuery instead!
Binom.Utils.SetHtml = function ($obj, valueToPlace, txtOnly) {
    try {
        if (!this.IsNullOrEmpty($obj)) {
            if (this.IsNullOrEmpty(valueToPlace)) valueToPlace = "";
            if (txtOnly != null && txtOnly == true) {
                //$obj.text(valueToPlace);
                $obj.innerText = valueToPlace;
            }
            else {
                //$obj.html(valueToPlace);
                $obj.innerHTML = valueToPlace;
            }
        }
    }
    catch (errObj) { this.NotifyUser("SetHtml Error!", errObj, this.GetArguments(arguments)); }
};
/// Retrieves innerHTML from specified document object, returns string. Obsolite use jQuery instead!
Binom.Utils.GetHtml = function ($obj, txtOnly) {
    var htmlData = null;
    try {
        if (!this.IsNullOrEmpty($obj)) {
            if (txtOnly != null && txtOnly == true) {
                htmlData = $obj.text;
            }
            else {
                htmlData = $obj.html;
            }
        }
    }
    catch (errObj) { this.NotifyUser("GetHtml Error!", errObj, this.GetArguments(arguments)); }
    return htmlData;
};
/// Show-Hide switch based on style.display  = "block" or "none" values
Binom.Utils.ShowHide = function ($obj) {
    try {
        $obj.toggle($obj.show(), $obj.hide());
    }
    catch (errObj) { this.NotifyUser("ShowHide Error!", errObj, this.GetArguments(arguments)); }
};
/// Sets focus on specified object (input tags, etc.)
Binom.Utils.SetFocus = function ($obj) {
    try {
        if (!this.IsNullOrEmpty($obj)) $obj.focus();
    }
    catch (errObj) { this.NotifyUser("SetFocus Error!", errObj, this.GetArguments(arguments)); }
};
// Detects if specified keycode is pressed, returns boolean
Binom.Utils.IsKey = function ($code, $eventObj) {
    var keyDetected = false;
    try {
        if (!this.IsNullOrEmpty($code) && Number($code) != 0 && $eventObj != null) {
            var key = this.GetKeyCodeByEvent($eventObj);
            if (!this.IsNullOrEmpty(key) && key > 0 && key == $code) keyDetected = true;
        }
    }
    catch (errObj) { this.NotifyUser("IsKey Error!", errObj, this.GetArguments(arguments)); }
    return keyDetected;
};
/// Detects pressed key
Binom.Utils.GetKeyCodeByEvent = function ($eventObj) {
    var key = 0;
    try {
        if (!this.IsNullOrEmpty($eventObj)) key = ($eventObj.which) ? $eventObj.which : event.keyCode;
    }
    catch (errObj) { this.NotifyUser("GetKeyCodeByEvent Error!", errObj, this.GetArguments(arguments)); }
    return key;
};
/// Detects if enter is pressed, returns boolean
Binom.Utils.IsEnterPressed = function ($eventObj) {
    return this.IsKey(13, $eventObj);
};
/// Bookmark any url, Opera is exception. For Opera bookmarks create <a href="bookmarkUrl" title="bookmarkTitle" rel="sidebar"> link. Method will return "true" if this type of bookmark link is needed. If no title or url is provided user will bookmark current page.
/*
CODE Example:
<a href="{urlToBookmark or blank}" title="{titleOfBookmark or blank}" rel="sidebar" onclick="return Binom.Utils.Bookmark();">Bookmark</a>

NOTE:
Link will be active only if viewed in Opera, other browsers will execute javascript code for adding bookmark and will not process link.
*/
Binom.Utils.Bookmark = function (bookmarkTitle, bookmarkUrl, msg) {
    var useBookmarkLink = false;
    try {
        // Setting default values
        if (this.IsNullOrEmpty(bookmarkTitle)) bookmarkTitle = document.title;
        if (this.IsNullOrEmpty(bookmarkUrl)) bookmarkUrl = location.href;
        if (this.IsNullOrEmpty(msg)) msg = "Bookmark: Ctrl-D"; // For undefined browsers only

        if (window.sidebar) {
            // Firefox
            window.sidebar.addPanel(bookmarkTitle, bookmarkUrl, "");
        }
        else if (document.all && !window.opera) {
            // IE
            window.external.AddFavorite(bookmarkUrl, bookmarkTitle);
        }
        else if (window.opera && window.print) {
            // Opera needs bookmark defined as <a href="bookmarkUrl" title="bookmarkTitle" rel="sidebar">
            useBookmarkLink = true;
        }
        else {
            // Not defined browsers (Netscape and Crome)
            if (!this.IsNullOrEmpty(msg)) alert(msg);
        }
    }
    catch (errObj) { this.NotifyUser("Bookmark Error!", errObj, this.GetArguments(arguments)); }
    return useBookmarkLink;
}
/// Opens new window
Binom.Utils.OpenWindow = function ($url, w, h, resizable, scrollable, winName) {
    try {
        if (!this.IsNullOrEmpty($url)) {
            // Default values
            var defW = 100;
            var defH = 100;
            var defResizable = true;
            var defScrollable = true;
            var defWinName = null;

            // Hardcoded values
            var pStatus = "no";

            // Seting defaults if needed
            if (this.IsNullOrEmpty(w) || w < 0) winWidth = defW;
            if (this.IsNullOrEmpty(h) || h < 0) winHeight = defH;
            if (this.IsNullOrEmpty(resizable)) resizable = defResizable;
            if (this.IsNullOrEmpty(scrollable)) scrollable = defScrollable;
            if (this.IsNullOrEmpty(winName)) winName = defWinName;

            var resizableFormated = resizable;
            if (resizable == true) resizableFormated = "yes";
            if (resizable == false) resizableFormated = "no";

            var scrollableFormated = scrollable;
            if (scrollableFormated == true) scrollableFormated = "yes";
            if (scrollableFormated == false) scrollableFormated = "no";

            // Opening window
            var newWindow = window.open($url, winName, "resizable=" + resizableFormated + ", scrollbars=" + scrollableFormated + ", status=" + pStatus + ", width=" + w + ", height=" + h);
            if (newWindow != null) newWindow.focus();
        }
    }
    catch (errObj) { this.NotifyUser("OpenWindow Error!", errObj, this.GetArguments(arguments)); }
};
/// (RegEx)Detects if email value is valid, returns boolean
Binom.Utils.IsValidMail = function ($mail) {
    var isValid = false;
    try {
        if (!this.IsNullOrEmpty(mail) && mail.length > 5) {
            var emailReg = "^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,4}$";
            var regex = new RegExp(emailReg, "i");
            isValid = regex.test($mail);
        }
    }
    catch (errObj) { this.NotifyUser("IsValidMail Error!", errObj, this.GetArguments(arguments)); }
    return isValid;
};
/// Gets flash object on document based on id, returns object
Binom.Utils.GetFlashObjById = function ($flashId) {
    var obj = null;
    try {

        if (!this.IsNullOrEmpty($flashId)) {
            obj = $("#" + $flashId);
            if (this.IsNullOrEmpty(obj)) {
                if (window.document[$flashId]) {
                    obj = window.document[$flashId];
                }
                else if (navigator.appName.indexOf("Microsoft Internet") == -1) {
                    if (document.embeds && document.embeds[$flashId])
                        obj = document.embeds[$flashId];
                }
            }
        }
    }
    catch (errObj) { this.NotifyUser("GetFlashObjById Error!", errObj, this.GetArguments(arguments)); }
    return obj;
};
/// Gets value of checked form field
Binom.Utils.GetCheckedValue = function ($obj) {
    var selectedValue = "";
    try {
        if (!this.IsNullOrEmpty($obj) && $obj.checked) selectedValue = $obj.val();
    }
    catch (errObj) { this.NotifyUser("GetCheckedValue Error!", errObj, this.GetArguments(arguments)); }
    return selectedValue;
};
/// Removes all options tags from passed select tag reference
Binom.Utils.RemoveAllOptionTags = function ($obj) {
    try {
        if (!this.IsNullOrEmpty($obj)) $obj.children().remove();
    }
    catch (errObj) { this.NotifyUser("RemoveAllOptionTags Error!", errObj, this.GetArguments(arguments)); }
};
/// Add option tags to specified select form tag
Binom.Utils.AddOptionTags = function ($obj, $arr, firstItemTitle, firstItemValue) {
    try {
        if (!this.IsNullOrEmpty($obj) && !this.IsNullOrEmpty($arr)) {
            // Default values
            var defItemTitle = "-";
            var defItemValue = 0;

            // Seting defaults, adding first item if needed
            if (!this.IsNullOrEmpty(firstItemTitle) || !this.IsNullOrEmpty(firstItemValue)) {
                if (!this.IsNullOrEmpty(firstItemTitle)) firstItemTitle = defItemTitle;
                if (!this.IsNullOrEmpty(firstItemValue)) firstItemValue = defItemValue;

                $obj.append('<option value="' + firstItemValue + '">' + firstItemTitle + '</option>');
            }

            // Add tags
            for (var itemIndex in $arr) $obj.append('<option value="' + $arr[itemIndex][1] + '">' + $arr[itemIndex][0] + '</option>');
        }
    }
    catch (errObj) { this.NotifyUser("AddOptionTags Error!", errObj, this.GetArguments(arguments)); }
};
/// Parses querystring from url, if url is not specified method will parse document.location.href, returns array of query string keys and values
Binom.Utils.ParseQueryStrings = function (uri) {
    var arrQueryInfo = null;
    try {
        if (uri != null && document != null && document.location != null && document.location.href != null) uri = unescape(document.location.href);
        var arrUrl = uri.split("?");
        if (!this.IsNullOrEmpty(arrUrl)) {
            var arrQueryStrings = arrUrl[1].split("&");
            if (!this.IsNullOrEmpty(arrQueryStrings)) {
                arrQueryInfo = new Array(arrQueryStrings.length / 2);
                var queryIndex = 0;
                for (var itemIndex = 0; itemIndex < arrQueryStrings.length; itemIndex++) {
                    var arrCurrentQuery = arrQueryStrings[itemIndex].split("=");
                    if (!this.IsNullOrEmpty(arrCurrentQuery)) {
                        var keyName = arrCurrentQuery[0];
                        if (!this.IsNullOrEmpty(keyName)) {
                            var keyValue = arrCurrentQuery[1];
                            arrQueryInfo[queryIndex] = new Array(keyName, keyValue);
                            queryIndex++;
                        }
                    }
                }
            }
        }
    }
    catch (errObj) { this.NotifyUser("ParseQueryStrings Error!", errObj, this.GetArguments(arguments)); }
    return arrQueryInfo;
};
/// Get query string value from url, based on querystring name
Binom.Utils.GetQueryString = function ($key, defaultValue, arrQueryInfo) {
    var queryStringValue = defaultValue;
    try {
        if (!this.IsNullOrEmpty($key)) {
            arrQueryInfo = this.ParseQueryStrings();
            if (!this.IsNullOrEmpty(arrQueryInfo)) {
                // extracting key names into one dim. array
                var arrKeys = new Array(arrQueryInfo.length);
                for (var itemIndex in arrQueryInfo) {
                    arrKeys[itemIndex] = arrQueryInfo[itemIndex][0];
                }
                // Searching array
                if (!this.IsNullOrEmpty(arrKeys)) {
                    var arrIndexAt = this.SearchArray(arrKeys, $key);
                    if (arrIndexAt != null && arrIndexAt.length == 1) queryStringValue = arrQueryInfo[arrIndexAt[0]][1];
                }
            }
        }
    }
    catch (errObj) { this.NotifyUser("GetQueryString Error!", errObj, this.GetArguments(arguments)); }
    return queryStringValue;
};
/// Search key can be string or Regex, returns array of found index locations, array.indexOf can be used as replacement
Binom.Utils.SearchArray = function ($arrData, $toFind) {
    var arrFoundData = new Array();
    try {
        if (!this.IsNullOrEmpty($arrData) && !this.IsNullOrEmpty($toFind)) {
            for (var index = 0; index < $arrData.length; index++) {
                if (typeof $toFind == 'function') {
                    // Searching with regex
                    if ($toFind.test($arrData[index]) == true)// execute regex
                    {
                        if (arrFoundData == null) arrFoundData = new array();
                        arrFoundData.push(index);
                    }
                }
                else {
                    // Searching for string
                    if ($arrData[index].toLowerCase() === $toFind.toLowerCase())// ignore case
                    {
                        if (arrFoundData == null) arrFoundData = new array();
                        arrFoundData.push(index);
                    }
                }
            }
        }
    }
    catch (errObj) { this.NotifyUser("SearchArray Error!", errObj, this.GetArguments(arguments)); }
    return arrFoundData;
};
/// Strip string from left
Binom.Utils.Left = function ($str, $index) {
    var strFormated = $str;
    try {
        if (!this.IsNullOrEmpty($str) && !this.IsNullOrEmpty($index)) {
            if ($index < $str.length) strFormated = $str.substring(0, $index);
        }
    }
    catch (errObj) { this.NotifyUser("Left Error!", errObj, this.GetArguments(arguments)); }
    return strFormated;
};
/// Strip string from right
Binom.Utils.Right = function ($str, $index) {
    var strFormated = $str;
    try {
        if (!this.IsNullOrEmpty($str) && !this.IsNullOrEmpty($index)) {
            var strLength = $str.length;
            if ($index < strLength) strFormated = $str.substring(strLength, strLength - $index);
        }
    }
    catch (errObj) { this.NotifyUser("Right Error!", errObj, this.GetArguments(arguments)); }
    return strFormated;
};
/// Gets selected text, if obj is provided method will assume that obj(obj.value != null) is input, textarea or similar form field
Binom.Utils.GetSelectedText = function (obj) {
    var selectedText = "";
    try {
        if (document.selection)// IE
        {
            // Get selected text on any element in document
            selectedText = document.selection.createRange().text;
        }
        else // Opera, FF
        {
            if (obj != null && obj.value != null) {
                // Get selected text in input
                selectedText = obj.value.substr(obj.selectionStart, obj.selectionEnd - obj.selectionStart);
            }
            else {
                // Get selected text on document
                selectedText = window.getSelection();
            }
        }
    }
    catch (errObj) { this.NotifyUser("GetSelectedText Error!", errObj, this.GetArguments(arguments)); }
    return selectedText;
};
/// Limits field based on character count
Binom.Utils.OnKeyLimitCharsCount = function ($eventObj, $fieldCountLimit) {
    var acceptKey = true;
    try {
        if ($eventObj != null && $fieldCountLimit != null && Number($fieldCountLimit) != NaN && Number($fieldCountLimit) > 0) {
            var obj = $eventObj.srcElement;
            if (obj == null) obj = $eventObj.target;
            if (obj != null && obj.value != null) {
                acceptKey = false;
                var currentLength = obj.value.length;
                if (currentLength < Number($fieldCountLimit)) acceptKey = true;
            }
        }
    }
    catch (errObj) { this.NotifyUser("OnKeyLimitCharsCount Error!", errObj, this.GetArguments(arguments)); }
    return acceptKey;
};
/// Calculates element offset, returns object (top, left, right, bottom, width, height). TODO: transform to jquery plugin
Binom.Utils.GetOffset = function ($obj) {
    var objOffset = null;
    try {
        if ($obj != null) {
            // Create object and defaults
            objOffset = new Object();
            objOffset.top = 0;
            objOffset.left = 0;
            objOffset.right = 0;
            objOffset.bottom = 0;
            objOffset.width = 0;
            objOffset.height = 0;

            // Climb up the nod tree
            var objTarget = $obj;
            while (objTarget != null) {
                objOffset.left += objTarget.offsetLeft;
                objOffset.top += objTarget.offsetTop;
                objTarget = objTarget.offsetParent;
            }

            // Detect window size
            var objWinInfo = this.GetWinInfo();
            var winW = (objWinInfo != null && objWinInfo.width) || 0;
            var winH = (objWinInfo != null && objWinInfo.height) || 0;

            objOffset.width = ($obj != null && $obj.offsetWidth) || $obj.offsetWidth;
            objOffset.height = ($obj != null && $obj.offsetHeight) || $obj.offsetHeight;

            if (winW > 0 && objOffset.width > 0) objOffset.right = winW - objOffset.width - objOffset.left;
            if (winH > 0 && objOffset.height > 0) objOffset.bottom = winH - objOffset.height - objOffset.top;
        }
    }
    catch (errObj) { this.NotifyUser("GetOffset Error!", errObj, this.GetArguments(arguments)); }
    return objOffset;
};
/// Element <div> or <span> reposition (posLeft or posRight should be specified for moving on X, posTop or posBottom should be specified for moving on Y), css{position:absolute;} will be set on repositioning obj. TODO: transform to jquery plugin
Binom.Utils.Reposition = function ($obj, posLeft, posTop, posRight, posBottom, w, h) {
    try {
        if (!this.IsNullOrEmpty($obj)) {
            // Force absolute position
            if ((posLeft != null && posLeft >= 0) || (posTop != null && posTop >= 0) || (posRight != null && posRight >= 0) || (posBottom != null && posBottom >= 0)) {
                if ($obj.style.position != "absolute") $obj.style.position = "absolute";
            }

            if (!this.IsNullOrEmpty(w)) $obj.style.width = w;
            if (!this.IsNullOrEmpty(h)) $obj.style.height = h;

            if (posLeft != null && posLeft >= 0) $obj.style.left = posLeft.toString() + "px";
            if (posTop != null && posTop >= 0) $obj.style.top = posTop.toString() + "px";

            // Detect window size
            var objWinInfo = this.GetWinInfo();
            var winW = (objWinInfo != null && objWinInfo.width) || 0;
            var winH = (objWinInfo != null && objWinInfo.height) || 0;

            if (posRight != null && posRight >= 0 && winW > 0) $obj.style.left = Number(winW - $obj.offsetWidth - posRight) + "px";
            if (posBottom != null && posBottom >= 0 && winH > 0) $obj.style.top = Number(winH - $obj.offsetHeight - posBottom).toString() + "px";
        }
    }
    catch (errObj) { this.NotifyUser("Reposition Error!", errObj, this.GetArguments(arguments)); }
};
/// Get window size and scrollbar position (width, height, scrollbar.left, scrollbar.top)
Binom.Utils.GetWinInfo = function () {
    var objWinInfo = null;
    try {
        // Create object and defaults
        objWinInfo = new Object();
        objWinInfo.width = 0;
        objWinInfo.height = 0;
        objWinInfo.scrollbar = new Object();
        objWinInfo.scrollbar.left = 0;
        objWinInfo.scrollbar.top = 0;

        if (document.body != null && document.body.clientWidth != null) {
            objWinInfo.width = document.body.clientWidth;
            objWinInfo.height = document.body.clientHeight;
            objWinInfo.scrollbar.left = document.body.scrollLeft;
            objWinInfo.scrollbar.top = document.body.scrollTop;
        }
        else if (window.innerWidth != null) {
            objWinInfo.width = window.innerWidth;
            objWinInfo.height = window.innerHeight;
            objWinInfo.scrollbar.left = window.pageXOffset;
            objWinInfo.scrollbar.top = window.pageYOffset;
        }
        else if (document.documentElement != null && document.documentElement.clientWidth != null) {
            objWinInfo.width = document.documentElement.clientWidth;
            objWinInfo.height = document.documentElement.clientHeight;
            objWinInfo.scrollbar.left = document.documentElement.scrollLeft;
            objWinInfo.scrollbar.top = document.documentElement.scrollTop;
        }
    }
    catch (errObj) { this.NotifyUser("GetWinInfo Error!", errObj); }
    return objWinInfo;
};
/// Disable or enable selection on page, if no params specified whole document.body will be unselectable. If whole document.body is UNSELECTABLE  Firefox will have SELECTABLE elements with style.postion="absolute", to disable such elements recall function and pass object reference to element with style.postion="absolute".
Binom.Utils.SetSelectionMode = function (obj, enable) {
    try {
        // Default values
        if (obj == null || obj == document) obj = document.body;
        if (enable == null) enable = false;

        if (!this.IsNullOrEmpty(obj)) {
            if (typeof obj.onselectstart != "undefined") {
                //IE
                obj.onselectstart = function () { return enable };
            }
            else if (obj.style != null && typeof obj.style.MozUserSelect != "undefined") {
                //Firefox 
                obj.style.MozUserSelect = (enable == false && "none") || "";
            }
            else {
                //All other browsers (ie: Opera)
                obj.onmousedown = function () { return enable };
            }
        }
    }
    catch (errObj) { this.NotifyUser("SwitchSelectionMode Error!", errObj, this.GetArguments(arguments)); }
};
/// Creates documents tags: html, head, body. TODO: change document tags to support better language sets
Binom.Utils.NewDocumentTags = function (cssFile, bodyStyle, encoding) {
    var documentTags = "";
    try {
        // TODO: Use UTF8 sa default, add char page to head
        // Default values
        if (encoding == null) encoding = "windows-1250";

        documentTags = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + encoding + "\">";
        if (cssFile != null && cssFile.length > 0) documentTags += "<link href=\"" + cssFile + "\" rel=\"stylesheet\" type=\"text/css\">";
        documentTags += "</head>";
        if (bodyStyle != null && bodyStyle.length > 0) bodyStyle = " style=\"" + bodyStyle + "\"";
        documentTags += "<body" + bodyStyle + "></body>";
        documentTags += "</html>";
    }
    catch (errObj) { this.NotifyUser("NewDocumentTags Error!", errObj, this.GetArguments(arguments)); }
    return documentTags;
};
/// Creates Rich Text Editor from any iframe object
Binom.Utils.CreateRTEIFrame = function ($obj, $documentTags, designMode, initialValue) {
    try {
        if (!this.IsNullOrEmpty($obj) && !this.IsNullOrEmpty($documentTags)) {
            var objTarget = this.GetIFrameDocument($obj);

            if (objTarget != null) {
                // Create Rich Text Editor
                this.FocusIFrame($obj);
                objTarget.designMode = (designMode != null && designMode) || "On"; // Default is "On"
                objTarget.open();
                objTarget.write($documentTags);
                objTarget.close();

                // Fill data
                if (initialValue != null && initialValue.length > 0 && objTarget.body != null) this.SetHtml(objTarget.body, initialValue);
            }
        }
    }
    catch (errObj) { this.NotifyUser("CreateRTAIFrame Error!", errObj, this.GetArguments(arguments)); }
};
/// To get complete list search for "execCommand Command Identifiers", some of the options: Bold, Italic, Underline, JustifyCenter, JustifyFull, JustifyLeft, JustifyRight, Copy, Cut, Paste, Delete, CreateLink, FontName, FontSize, FontColor, Indent, Outdent, InsertImage, Print, Refresh, RemoveFormat, SelectAll, Bookmark, UnBookmark, Unselect, SaveAs.
Binom.Utils.RTECommand = function ($obj, $command, option) {
    try {
        if (!this.IsNullOrEmpty($obj) && !this.IsNullOrEmpty($command)) {
            var objTarget = this.GetIFrameDocument($obj);

            if (objTarget != null) {
                // Execute Rich Text Editor Command, based on specified Command Identifier
                objTarget.execCommand($command, false, option);
                this.FocusIFrame($obj);
            }
        }
    }
    catch (errObj) { this.NotifyUser("RTACommand Error!", errObj, this.GetArguments(arguments)); }
};
/// Focus IFrame document
Binom.Utils.FocusIFrame = function ($obj) {
    try {
        if (!this.IsNullOrEmpty($obj)) {
            if ($obj.contentWindow != null) {
                $obj.contentWindow.focus();
            }
            else if ($obj.contentDocument != null) {
                $obj.contentDocument.focus();
            }
        }
    }
    catch (errObj) { this.NotifyUser("FocusFrame Error!", errObj, this.GetArguments(arguments)); }
};
/// Retrieves IFrame document object
Binom.Utils.GetIFrameDocument = function ($obj) {
    var objTarget = null;
    try {
        if (!this.IsNullOrEmpty($obj)) {
            if ($obj.contentWindow != null) {
                objTarget = $obj.contentWindow.document;
            }
            else if ($obj.contentDocument != null) {
                objTarget = $obj.contentDocument;
            }
        }
    }
    catch (errObj) { this.NotifyUser("GetIFrameDocument Error!", errObj, this.GetArguments(arguments)); }
    return objTarget;
};
/// Copy iframe html content to field.value, returns iframe content html
Binom.Utils.CopyIFrameValue = function ($objSrc, objTarget) {
    var targetValue = "";
    try {
        if (!this.IsNullOrEmpty($obj) && !this.IsNullOrEmpty(objTarget)) {
            var objIframe = this.GetIFrameDocument($objSrc);
            if (objIframe != null && objIframe.body != null) {
                // Fetch iframe content
                targetValue = objIframe.contents()[0].documentElement.innerHTML;
                if (this.IsNullOrEmpty(targetValue)) targetValue = "";

                // Fill target field container
                if (objTarget != null) objTarget.val(targetValue);
            }
        }
    }
    catch (errObj) { this.NotifyUser("CopyIFrameValue Error!", errObj, this.GetArguments(arguments)); }
    return targetValue;
};

/// Reformats querystring values, passed value will be replaced or added to querystring or url
Binom.Utils.ReformatQueryString = function ($url, $fldID, fldValue) {
    var newLocation = $url;
    try {
        if (!this.IsNullOrEmpty($fldID) && !this.IsNullOrEmpty($url)) {
            var locationData = $url.split('?');
            var currQuery = locationData[1];
            newLocation = "";
            if (currQuery != null && currQuery.length > 0) {
                // Query string exists
                var currQueryStrings = currQuery.split('&');
                var queryFound = false;
                for (var i = 0; i < currQueryStrings.length; i++) {
                    var currentQuery = currQueryStrings[i].split('=');
                    if (currentQuery[0].toLowerCase() == $fldID.toLowerCase()) {
                        if (!queryFound) {
                            queryFound = true;
                            if (newLocation != null && newLocation.length > 0) newLocation += "&";
                            newLocation += currentQuery[0] + "=" + fldValue;
                        }
                    }
                    else {
                        if (newLocation != null && newLocation.length > 0) newLocation += "&";
                        newLocation += currQueryStrings[i];
                    }
                }
                if (!queryFound) {
                    queryFound = true;
                    if (newLocation != null && newLocation.length > 0) newLocation += "&";
                    newLocation += $fldID + "=" + fldValue;
                }
                newLocation = locationData[0] + "?" + newLocation;
            }
            else {
                newLocation = $url + "?" + $fldID + "=" + fldValue;
            }
        }
    }
    catch (errObj) { this.NotifyUser("ReformatQueryString Error!", errObj, this.GetArguments(arguments)); }
    return newLocation;
};

/// Save javascript cookie
Binom.Utils.SetCookie = function ($name, $value, expires, path, domain, secure) {
    var saved = false;
    try {
        if ($name != null && $name.length > 0) {
            // set time, it's in milliseconds
            var today = new Date();
            today.setTime(today.getTime());

            if (expires) expires = expires * 1000 * 60 * 60 * 24;
            var expiresDate = new Date(today.getTime() + (expires));

            document.cookie = $name + "=" + escape($value) +
				((expires) ? ";expires=" + expiresDate.toGMTString() : "") +
				((path) ? ";path=" + path : "") +
				((domain) ? ";domain=" + domain : "") +
				((secure) ? ";secure" : "");
            saved = true;
        }
    }
    catch (errObj) { this.NotifyUser("SetCookie Error!", errObj, this.GetArguments(arguments)); }
    return saved;
};
/// Retreive javascript cookie
Binom.Utils.GetCookie = function ($name) {
    var cookieValue = null;
    try {
        if ($name != null && $name.length > 0) {
            // first we'll split this cookie up into name/value pairs
            // note: document.cookie only returns name=value, not the other components
            var allCookies = document.cookie.split(';');
            var tempCookie = null;
            var cookieName = "";
            var cookieFound = false;
            for (i = 0; i < allCookies.length; i++) {
                // now we'll split apart each name=value pair
                tempCookie = allCookies[i].split('=');

                // and trim left/right whitespace while we're at it
                cookieName = tempCookie[0].replace(/^\s+|\s+$/g, '');

                // if the extracted name matches passed check_name
                if (cookieName == $name) {
                    cookieFound = true;
                    // we need to handle case where cookie has no value but exists (no = sign, that is):
                    if (tempCookie.length > 1) cookieValue = unescape(tempCookie[1].replace(/^\s+|\s+$/g, ''));

                    // note that in cases where cookie is initialized but no value, null is returned
                    break;
                }
                tempCookie = null;
                cookieName = "";
            }
            if (!cookieFound) cookieValue = null;
        }
    }
    catch (errObj) { this.NotifyUser("GetCookie Error!", errObj, this.GetArguments(arguments)); }
    return cookieValue;
};

/// Toggle all childs class within container
Binom.Utils.ToggleClass = function ($objSrc, $class1, $class2) {
    try {
        if (!this.IsNullOrEmpty($objSrc) && (!this.IsNullOrEmpty($class1) || !this.IsNullOrEmpty($class2))) {
            var class1List = null;
            if (!this.IsNullOrEmpty($class1)) class1List = $objSrc.find("." + $class1);
            if (class1List != null && class1List.length > 0) {
                class1List.removeClass($class1);
                class1List.addClass($class2);
            }
            else {
                var class2List = null;
                if (!this.IsNullOrEmpty($class2)) class2List = $objSrc.find("." + $class2);
                if (class2List != null && class2List.length > 0) {
                    class2List.removeClass($class2);
                    class2List.addClass($class1);
                }
            }
        }
    }
    catch (errObj) { this.NotifyUser("ToggleClass Error!", errObj, this.GetArguments(arguments)); }
};
/// Floating layer 100% with centered div
Binom.Utils.ShowPopup = function ($pWidth, $pHeight, $color, $opacity, $maskID, $panelID) {
    var emptyOrNull = true;
    try {
        if ($opacity > 1) $opacity = 1;
        $("#" + $maskID).css("position", "fixed").css("width", "100%").css("height", "100%").css("background-color", $color).css("opacity", $opacity).css("z-index", "10000").css("left", "0").css("top", "0").show();
        $("#" + $panelID).css("position", "fixed").css("left", "50%").css("top", "50%").css("width", $pWidth.toString() + "px").css("height", $pHeight.toString() + "px").css("z-index", "10001").css("margin-left", Number($pWidth * -0.5).toString() + "px").css("margin-top", Number($pHeight * -0.5).toString() + "px").show();
    }
    catch (errObj) { this.NotifyUser("ShowPopup Error!", errObj, this.GetArguments(arguments)); }
    return emptyOrNull;
};

// Scrolling detection
(function () {

    var special = jQuery.event.special,
        uid1 = 'D' + (+new Date()),
        uid2 = 'D' + (+new Date() + 1);

    special.scrollstart = {
        setup: function () {

            var timer,
                handler = function (evt) {

                    var _self = this,
                        _args = arguments;

                    if (timer) {
                        clearTimeout(timer);
                    } else {
                        evt.type = 'scrollstart';
                        jQuery.event.handle.apply(_self, _args);
                    }

                    timer = setTimeout(function () {
                        timer = null;
                    }, special.scrollstop.latency);

                };

            jQuery(this).bind('scroll', handler).data(uid1, handler);

        },
        teardown: function () {
            jQuery(this).unbind('scroll', jQuery(this).data(uid1));
        }
    };

    special.scrollstop = {
        latency: 3000,
        setup: function () {

            var timer,
                    handler = function (evt) {

                        var _self = this,
                        _args = arguments;

                        if (timer) {
                            clearTimeout(timer);
                        };

                        timer = setTimeout(function () {
                            timer = null;
                            evt.type = 'scrollstop';
                            jQuery.event.handle.apply(_self, _args);

                        }, special.scrollstop.latency);

                    };

            jQuery(this).bind('scroll', handler).data(uid2, handler);

        },
        teardown: function () {
            jQuery(this).unbind('scroll', jQuery(this).data(uid2));
        }
    };

})();

