﻿// jPixeliT - javascript library v1.022
// Written by Miron Abramson


// Ajax object
var Ajax = window.Ajax = new AjaxManager();

// Cache object
var Cache = window.Cache = new CacheManager();

Ajax.OnError = window.Ajax.OnError = Error;
window.onerror = Error;

// Show error message
function Error(err) {
    alert(Messages.GetString('ERROR', err));
}

///////////////////////////////////////
//          Constants               //
//////////////////////////////////////

// Messages
var Messages = new function() { };

Messages.ERROR = "An unexpected error accured.\n\r Detailes: {0}";

Messages.GetString = function(strString, args) {
    return String.Format(eval('Messages.' + strString), ArrayFromArgs(arguments).slice(1));
}

//////////////////////////////////////////////////////////////////////////////////////////
//                          Ajax actions Class                                  
//////////////////////////////////////////////////////////////////////////////////////////
function AjaxManager() {
    this.OnError;
    this._timeout = 40000; // 40 seconds time out
    this._xmlHttpRequest = null;
    this._timer = null;
    this._started = false;
    var _this = this;
    this._onError = function(e) {
        _this.CancelRequest();
        if (_this.OnError) _this.OnError(e);

    }
    this._onTimeout = function() {
        _this.CancelRequest();
        _this._onError('timeout');
    }
    this._clearTimeOut = function() {
        if (_this._timer != null) {
            window.clearTimeout(_this._timer);
            _this._timer = null;
        }
    }
    this.CancelRequest = function() {
        if (_this._xmlHttpRequest && _this._started) {
            _this._xmlHttpRequest.abort();
        }
        _this._started = false;
        _this._requestCompleted();
    }
    this._get_httpVerb = function(data) {
        if (data === null) {
            return "GET";
        }
        return "POST";
    }
    this._requestCompleted = function() {
        _this._clearTimeOut();
        if (_this._xmlHttpRequest != null) {
            _this._xmlHttpRequest.onreadystatechange = Function.emptyMethod;
            _this._xmlHttpRequest = null;
        }
        _this._started = false;
    }
    this.ExecutePageMethod = function ExecutePageMethod(pageUrl, methodName, async, data, callBackMethod) {
        ///	<summary>
        ///		Access a web page and call a specified method in it
        ///
        /// Drop the following lines in the desired page event:
        ///
        ///  // Invoke method that been called from Ajax...
        ///  if (Request.PathInfo != null && Request.PathInfo.Length > 1)
        ///  {
        ///      string methodName = Request.PathInfo.Substring(1);
        ///      MethodInfo theMethod = this.GetType().GetMethod(methodName);
        ///      object ret = theMethod.Invoke(this, null);
        ///      Response.Clear();
        ///      Response.ContentType = "text/plain";
        ///      Response.Write(ret);
        ///      Response.End();
        ///      return;
        ///  }
        ///
        ///	</summary>
        /// <param name="pageUrl" type="String">The page url to call</param>
        /// <param name="methodName" type="String">The method name witch need to be called</param>
        /// <param name="async" type="Boolen">Excute the call async or not</param>
        /// <param name="data" type="String">The post data ('name1=value1&name2=value2')</param>
        /// <param name="callBackMethod" type="function(String)">The mathod to call after the call was made</param>
        var url = pageUrl;
        var queryString = '';
        var qsStart = pageUrl.indexOf('?');
        if (qsStart !== -1) {
            url = pageUrl.substr(0, qsStart);
            queryString = pageUrl.substr(qsStart);
        }
        url += ("/" + encodeURIComponent(methodName) + queryString);
        return this.ExecuteRequest(url, async, data, callBackMethod);
    }
    this.ExecuteRequest = function(serverUrl, async, data, callBackMethod) {
        ///	<summary>
        ///		Access a server url using 'ajax' technic
        ///	</summary>
        /// <param name="serverUrl" type="String">The page url to call</param>
        /// <param name="async" type="Boolen">Excute the call async or not</param>
        /// <param name="data" type="String">The post data ('name1=value1&name2=value2')</param>
        /// <param name="callBackMethod" type="function(String)">The mathod to call after the call was made</param>
        if (this._xmlHttpRequest) {
            this._clearTimeOut();
            this._xmlHttpRequest.onreadystatechange = Function.emptyMethod;
            this._xmlHttpRequest.abort();
            this._xmlHttpRequest = null;
        }
        this._xmlHttpRequest = new XMLHttpRequest();
        if (!this._xmlHttpRequest) {
            _this._onError("Your browser does not support Ajax"); return;
        }
        var _httpVerb = this._get_httpVerb(data);
        this._xmlHttpRequest.open(_httpVerb, serverUrl, async);
        this._xmlHttpRequest.setRequestHeader('PixeliT-Ajax', 'true');
        if (_httpVerb === "POST") {
            this._xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
            if (!data) {
                data = "";
            }
        }
        else {
            this._xmlHttpRequest.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
            this._xmlHttpRequest.setRequestHeader("Cache-Control", "no-cache");
        }
        if (async) {
            this._xmlHttpRequest.onreadystatechange = function() {
                if (_this._xmlHttpRequest.readyState == 4) {
                    try {
                        var _responseText = _this._xmlHttpRequest.responseText;
                        _this._requestCompleted();
                        if (callBackMethod != null) {
                            callBackMethod(_responseText, serverUrl);
                        }
                    } catch (e) { _this._onError(e); };
                }
            }
        }
        try {
            this._timer = window.setTimeout(Delegate(this, this._onTimeout), this._timeout);
            this._xmlHttpRequest.send(data);
            this._started = true;
        } catch (e) { _this._onError(e); };

        if (!async && typeof (callBackMethod) != 'function') {
            if (!_this._xmlHttpRequest) return "";
            var _responseText = _this._xmlHttpRequest.responseText;
            _this._requestCompleted();
            return _responseText;
        }
        if (!async && typeof (callBackMethod) == 'function') {
            if (!_this._xmlHttpRequest) return;
            var _responseText = _this._xmlHttpRequest.responseText;
            _this._requestCompleted();
            callBackMethod(_responseText, serverUrl);
        }
    }
    this.GetFormPostData = function() {
        ///	<summary>
        ///		Get all form emlenets & values as string ready to be sent by the Execution methods
        ///	</summary>
        var sb = new StringBuilder();
        var inputElementsCollection = document.getElementsByTagName("input");
        if (inputElementsCollection) {
            this.ConcatFormValues(inputElementsCollection, sb);
        }
        inputElementsCollection = document.getElementsByTagName("textarea");
        if (inputElementsCollection) {
            this.ConcatFormValues(inputElementsCollection, sb);
        }
        inputElementsCollection = document.getElementsByTagName("select");
        if (inputElementsCollection) {
            this.ConcatFormValues(inputElementsCollection, sb);
        }
        inputElementsCollection = document.getElementsByTagName("button");
        if (inputElementsCollection) {
            this.ConcatFormValues(inputElementsCollection, sb);
        }
        if (sb.length > 0)
            return sb.toString().substring(1, sb.length);
        return '';
    }

    this.ConcatFormValues = function ConcatFormValues(inputElementsCollection, sb) {
        for (var index = 0; index < inputElementsCollection.length; index++) {
            if (inputElementsCollection[index].id != "__EVENTTARGET" && inputElementsCollection[index].id != "__EVENTARGUMENT" && inputElementsCollection[index].id != "__VIEWSTATE")
                sb.Append("&" + inputElementsCollection[index].id + "=" + escape(encodeURI(inputElementsCollection[index].value)));
        }
    }
}
// Init the http request object
if (!window.XMLHttpRequest) {
    window.XMLHttpRequest = function getXMLHttpRequest() {
        var msTypes = ['Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP'];
        for (var i = 0, l = msTypes.length; i < l; i++) {
            try {
                return new ActiveXObject(msTypes[i]);
            }
            catch (ex) {
            }
        }
        return null;
    }
}

//////////////////////////////////////////////////////////////////////////////////////////
//                          Cache manager Class                                  
//////////////////////////////////////////////////////////////////////////////////////////
function CacheManager() {
    this._cache = new Array();
    this.Insert = function(key, value) {
        this._cache[key] = value;
    }
    this.Get = function(key) {
        return this._cache[key];
    }
    this.Contains = function(key) {
        return String.IsNullOrEmpty(this._cache[key]) ? false : true;
    }
}

//////////////////////////////////////////////////////////////////////////////////////////
//                          StringBuilder Class                                  
//////////////////////////////////////////////////////////////////////////////////////////
function StringBuilder(value) {
    this._buffer = [];
    this.length = 0;
    if ((typeof (value) !== 'undefined' && value !== null && value != '')) {
        var val = value.toString();
        this._buffer = [val];
        this.length = val.length;
    }

    this.Append = function(value) {
        if ((typeof (value) !== 'undefined' && value !== null && value !== '')) {
            var val = value.toString();
            this._buffer[this._buffer.length] = val;
            this.length += val.length;
        }
        return this;
    }

    this.AppendFormat = function(format, args) {
        var result = format;
        for (var i = 1; i < args.length; i++) {
            if (typeof (arguments[i]) === 'undefined') arguments[i] = '';
            result = result.replace(new RegExp('\\{' + (i - 1) + '\\}', 'g'), args[i].toString());
        }
        return this.Append(result);
    }

    this.Clear = function() {
        this._buffer = [];
        this.length = 0;
    }

    this.toString = function() {
        return this._buffer.join('');
    }
}

/////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////
//                 Helper methods                 //
////////////////////////////////////////////////////

//
//  Fade in an object
//
function FadeIn(elmId, speed, callback) {
    var obj = $getElement(elmId);
    if (callback)
        obj.OnFadeInComplete = callback;
    DoFadeIn(obj, 0, speed);

}

function DoFadeIn(obj, opacity, speed) {
    if (opacity < 100) {
        SetOpacity(obj, opacity);
        opacity += speed;
        setTimeout(function() { DoFadeIn(obj, opacity, speed); }, 50);
        //   window.setTimeout("FadeIn('" + objId + "'," + opacity + ")", 80);
    }
    else {
        SetOpacity(obj, 100);
        if (obj.style.filter && obj.style.removeAttribute) { try { obj.style.removeAttribute("filter"); } catch (err) { } }
        obj.style.zoom = '';
        if (obj.OnFadeInComplete) {
            obj.OnFadeInComplete();
        }
    }
}

//
//  Fade out an object
//
function FadeOut(elmId, speed, callback) {
    var obj = $getElement(elmId);
    if (callback)
        obj.OnFadeOutComplete = callback;
    DoFadeOut(obj, 100, speed);
}

function DoFadeOut(obj, opacity, speed) {
    if (opacity > 0) {
        SetOpacity(obj, opacity);
        opacity -= speed;
        setTimeout(function() { DoFadeOut(obj, opacity, speed); }, 50);
    }
    else {
        SetOpacity(obj, 0);
        if (obj.OnFadeOutComplete) {
            obj.OnFadeOutComplete();
        }
    }
}

//
//  Cross-Browser 'set opacity' 
//
function SetOpacity(obj, opacity) {
    opacity = (opacity >= 100) ? 99.999 : opacity;
    opacity = (opacity < 0) ? 0 : opacity;
    obj.style.zoom = 1; // Stupied hack for IE
    obj.style.filter = "alpha(opacity=" + opacity + ")";
    obj.style.KHTMLOpacity = (opacity / 100);
    obj.style.MozOpacity = (opacity / 100);
    obj.style.opacity = (opacity / 100);
}

//
//  Set element innerHTML, and execute the javascript code in it
//
function SetInnerHTML(elementId, text) {
    var elm = $getElement(elementId);
    if (elm) {
        if (elm.innerHTML == text)
            return;
        elm.innerHTML = text;
        var x = elm.getElementsByTagName("script");
        for (var i = 0; i < x.length; i++) {
            eval(x[i].text);
        }
    }
}
//
//  Check if the client berowser is Fuc... Internet Explorer
//
function IsIE() {
    return navigator.userAgent.indexOf("MSIE") >= 0
}
//
//  Remove a given suffix from a string (if exist)
//
function RemoveSuffix(value, suffix) {
    if (!String.IsNullOrEmpty(value) && value.EndsWith(suffix)) {
        return value.substring(0, value.length - suffix.length);
    }
    return value;
}

//
//  Get the scroll offset top & left
//
function getScrollOffset() {
    var x, y;
    if (self.pageYOffset) {
        x = self.pageXOffset;
        y = self.pageYOffset;
    }
    else {
        if (document.documentElement && document.documentElement.scrollTop) {
            x = document.documentElement.scrollLeft;
            y = document.documentElement.scrollTop;
        }
        else {
            if (document.body) {
                x = document.body.scrollLeft;
                y = document.body.scrollTop;
            }
        }
    }
    return { left: parseInt(x), top: parseInt(y) };
}

var ElementsCache = new CacheManager();
//
//  Get an element by Id
//
window.$getElement = function $getElement(elementID) {
    if (typeof (elementID) != 'string') return elementID;
    var elm = document.getElementById(elementID);
    if (elm) return elm;
    if (ElementsCache.Contains(elementID)) {
        return document.getElementById(ElementsCache.Get(elementID));
    }
    var reg = new RegExp(elementID + "$");
    var pageElements = document.getElementsByTagName("*");
    for (i = 0; i < pageElements.length; i++) {
        elm = pageElements[i];
        if (elm.id) {
            if (reg.test(elm.id)) {
                ElementsCache.Insert(elementID, elm.id);
                return elm;
            }
        }
    }
    return null;
}

//
// Get browser window width
//
function BrowserWidth() {
    if (window.innerWidth)
        return window.innerWidth;
    return document.body.clientWidth;
}
//
// Get browser window height
//
function BrowserHeight() {
    if (window.innerHeight)
        return window.innerHeight;
    return document.body.clientHeight;
}
//
// String.Format implementation
//
String.Format = function(format, args) {
    var result = format;
    for (var i = 1; i < arguments.length; i++) {
        if (typeof (arguments[i]) === 'undefined') arguments[i] = '';
        result = result.replace(new RegExp('\\{' + (i - 1) + '\\}', 'g'), arguments[i].toString());
    }
    return result;
}

//
//  String.Equals implementation
//
String.Equals = function(a, b, ignoreCase) {
    if (String.IsNullOrEmpty(a) || String.IsNullOrEmpty(b))
        return a == b;
    if (ignoreCase && typeof (a) == 'string' && typeof (b) == 'string') {
        if (ignoreCase == true) {
            return (a.toUpperCase() == a.toUpperCase());
        }
    }
    return (a == b);
}
//
// string.EndsWith implementation
//
String.prototype.EndsWith = function(suffix, ignoreCase) {
    if (!suffix) return false;
    if (suffix.length > this.length) return false;
    if (ignoreCase) {
        if (ignoreCase == true) {
            return (this.substr(this.length - suffix.length).toUpperCase() == suffix.toUpperCase());
        }
    }
    return (this.substr(this.length - suffix.length) === suffix);
}
//
// string.StartWith implementation
//
String.prototype.StartsWith = function(prefix, ignoreCase) {
    if (!prefix) return false;
    if (prefix.length > this.length) return false;
    if (ignoreCase) {
        if (ignoreCase == true) {
            return (this.substr(0, prefix.length).toUpperCase() == prefix.toUpperCase());
        }
    }
    return (this.substr(0, prefix.length) === prefix);
}
//
// string.Trim implementation
//
String.prototype.Trim = function() {
    return this.replace(/^\s+|\s+$/g, '');
}
//
// String.IsNullOrEmpty implementation
//
String.IsNullOrEmpty = function(value) {
    if (value) {
        if (typeof (value) == 'string') {
            if (value.length > 0)
                return false;
        }
        if (value != null)
            return false;
    }
    return true;
}
//
// Create an array from the arguments
//
function ArrayFromArgs(args) {
    var newArray = new Array();
    for (var i = 0; i < args.length; i++)
        newArray[i] = args[i];
    return newArray;
}
//
//  Create a delegate to a method
//
function Delegate(instance, method) {
    return function() {
        return method.apply(instance, arguments);
    }
}
//
// Define an empty method
//
Function.emptyMethod = function() {
}

//
//  Get mouse location
//
function GetMouseLocation(e) {
    x = e.clientX;
    y = e.clientY + getScrollOffset().top;
    return [x, y]
}
//////////////////////////////////////////////////////////////////
//              Validation methods                              //
//////////////////////////////////////////////////////////////////
function ValidatorTrim(s) {
    var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
    return (m == null) ? "" : m[1];
}
//
//  Validate if the input is valid email (empty input == valid)
//
function IsValidEmail(input) {
    if (ValidatorTrim(input).length == 0)
        return true;
    var rx = new RegExp("\\w+([-+.\']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
    var matches = rx.exec(input);
    return (matches != null && input == matches[0]);
}