﻿
jQuery.noConflict();


var VOID_ID = -1;
var KeyCodes = {
    ENTER : 13,
    ESC: 27
}

function _debug(msg) { }
function _alert(msg) { }


String.prototype.startsWith = function(str)
{
    return (this.match("^" + str) == str)
};
String.prototype.include = function(needle)
{
    return this.indexOf(needle) != -1;
};
String.prototype.unescapeHtml = function()
{
    var temp = document.createElement("div");
    temp.innerHTML = this;
    var result = temp.childNodes[0].nodeValue;
    temp.removeChild(temp.firstChild);
    return result;
} 

String.prototype.endsWith = function(str)
{
    return (this.match(str + "$") == str)
};

Function.prototype.wrapTryCatch = function()
{
    function update(array, args)
    {
        var arrayLength = array.length, length = args.length;
        while (length--) array[arrayLength + length] = args[length];
        return array;
    }

    var __method = this;
    return function()
    {
        var a = update([__method.bindMethod(this)], arguments);
        try
        {
            return __method.apply(this, a);
        }
        catch (err)
        {
            if (DEBUG_MODE) alert('tryCatch: ' + err);
        }
    }
}

// override jQuery.fn.bind to wrap every provided function in try/catch
var jQueryBind = jQuery.fn.bind;
jQuery.fn.bind = function(type, data, fn)
{
    if (fn || (data && typeof data == 'function'))
    {
        var origFn = (!fn && data && typeof data == 'function') ? data : fn;
        var wrappedFn = function()
        {
            try
            {
                origFn.apply(this, arguments);
            }
            catch (ex)
            {
                trackError(ex);
                // re-throw ex iff error should propogate
                // throw ex;
            }
        };
        fn = wrappedFn;
    }
    return jQueryBind.call(this, type, data, fn);
};

/**
* The "bind()" function extension from Prototype.js, extracted for general use
*
* @author Richard Harrison, http://www.pluggable.co.uk
* @author Sam Stephenson (Modified from Prototype Javascript framework)
* @license MIT-style license @see http://www.prototypejs.org/
*/
Function.prototype.bindMethod = function()
{
    // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Functions:arguments
    var _a = function(a) { return Array.prototype.slice.call(a); }

    if (arguments.length < 2 && (typeof arguments[0] == 'undefined')) return this;

    var __method = this, args = _a(arguments), object = args.shift();

    return function()
    {
        return __method.apply(object, args.concat(_a(arguments)));
    }
}


Function.prototype.curry = function()
{
    var method = this, args = Array.prototype.slice.call(arguments);
    return function()
    {
        return method.apply(this, args.concat(Array.prototype.slice.call(arguments)));
    };
};
Function.prototype.defer = function()
{
    setTimeout(this, 0);
}
Function.prototype.delay = function(seconds)
{
    setTimeout(this, seconds * 1000);
}

function isNumber(val)
{
    return /^-?((\d+\.?\d?)|(\.\d+))$/.test(val);
};

function isJquery(obj)
{
    if (obj === undefined) return false;
    if (obj.jQuery == undefined) return false;
    return true;
}




function trackError(err)
{
    var msg = 'Unknown error';
    if (err.message)
    {
        msg = err.message;
    }
    else if (typeof err == 'string' || typeof err == 'String')
    {
        msg = err;
    }

    try {
        jQuery.ajax(
        {
            type: 'POST',
            url: AppPath.VirtualPath + '/error/errorlogger.asmx/LogJavaScriptError',
            data: { details: msg }
        });
    }
    catch (e) {_alert('track postback error ' + e); }
    
    _alert('JavaScript error: ' + msg);
};

// Attach trackError to window's onerror event;
// use onerror instead of $(window).error( ... ) in order to get url and lineNo
window.onerror = function(msg, url, lineNo)
{
    trackError(' at line ' + lineNo + ' in file ' + url + '\n' + msg);
    // return true to stop error from propogating, false to allow propogation
    return false;
};



var Hash = jQuery.Class.create(
{
    nh: null,

    initialize: function(obj)
    {
        this.nh = (obj) ? obj : {};
    },

    getRequired: function(key)
    {
        return this.get(key);
    },
    get: function(key)
    {
        return this.nh[key];
    },

    getOptional: function(key, defaultValue)
    {
        return this.nh[key] || defaultValue;
    },

    set: function(key, value)
    {
        this.nh[key] = value;
    },

    unset: function(key)
    {
        delete this.nh[key];
    },

    each: function(f)
    {
        for (var i in this.nh)
        {
            if (typeof (this.nh[i]) != "function")
            {
                f({ key: i, value: this.nh[i] });
            }
        }
    },

    keys: function()
    {
        var k = [];
        for (var i in this.nh)
        {
            if (typeof (this.nh[i]) != "function")
            {
                k.push(i);
            }
        }
        return (k);
    },

    values: function()
    {
        var k = [];
        for (var i in this.nh)
        {
            if (typeof (this.nh[i]) != "function")
            {
                k.push(this.nh[i]);
            }
        }
        return (k);
    },

    elements: function()
    {
        var k = [];
        for (var i in this.nh)
        {
            if (typeof (this.nh[i]) != "function")
            {
                k.push({ key: i, value: this.nh[i] });
            }
        }
        return k;
    }

});

function $H(obj)
{
    return new Hash(obj);
}




jQuery.fn.identify = function(prefix)
{
    var i = 0;
    this.each(function()
    {
        if (jQuery(this).attr('id')) return;
        do
        {
            i++;
            var id = prefix + '_' + i;
        } while (document.getElementById(id) != null);
        jQuery(this).attr('id', id);
    });
    return jQuery(this).attr('id');
};

function includeJavascriptFile(filename) {
    var body = document.getElementsByTagName('head')[0];
    script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';
    body.appendChild(script);
}

(function($)
{
    $.fn.exists = function()
    {
        return this.length > 0;
    };


    $.fn.enable = function()
    {
        this.attr('disabled', '');
    };


    $.fn.disable = function()
    {
        this.attr('disabled', 'disabled');
    };


    $.fn.down = function(selector)
    {
        if (!selector)
        {
            var el = this[0] && this[0].firstChild;
            while (el && el.nodeType != 1)
                el = el.nextSibling;
            return $(el);
        }
        else
        {
            return $(this).find(selector + ":first");
        }
    };

    $.fn.up = function(selector)
    {
        if (!selector)
        {
            return $(this[0].parentNode);
        }
        else
        {
            return $(this).parents(selector + ":first");
        }
    };

    $.fn.classNames = function()
    {
        _alert("invoked classNames(). Use classes() instead");
        return this.classes();
    };

    $.fn.classes = function()
    {
        return this.attr('className').split(' ');
    };

    $.fn.findClassNameWithPrefix = function(classNamePrefix, removePrefix)
    {
        var classNames = this.classes();

        for (var i = 0; i < classNames.length; i++)
        {
            if (classNames[i].indexOf(classNamePrefix) == 0)
            {
                if (removePrefix)
                {
                    return classNames[i].substr(classNamePrefix.length);
                }
                return classNames[i];
            }
        }

        return null;
    };

    //tgr: pause is intended for clean delayed animation purposes
    //example : $("#mainImage").pause(5000).fadeOut();
    if ($.fn.pause)
    {
        _alert("WARNING jQuery.pause already defined!");
    };

    $.fn.pause = function(duration)
    {
        $(this).animate({ dummy: 1 }, duration);
        return this;
    };

    if ($.fn.dimension)
    {
        _alert("WARNING jQuery.dimension already defined!");
    }
    else
    {
        $.fn.dimension = function()
        {
            return { height: $(this).height(), width: $(this).width() };
        };
    }
    
    $.fn.diffOffsetParent = function()
    {
        if (this.length > 1)
        {
            _alert('we dont support more than one element just yet');
        }
        return this.diffOffset(this.offsetParent());
    };

    // mvl: calculates the true offset between this and ancestor, respecting scroll containers
    // (regular jquery functions will give you the absolute distance in pixels, ignoring any scroll).
    $.fn.diffOffset = function(ancestor)
    {
        ancestor = jQuery.getElement(ancestor);

        if (this.length > 1 || ancestor.length > 1)
        {
            _alert('we dont support more than one element just yet');
        }

        var result = { top: 0, left: 0 };

        var current = this;

        while (current.length > 0)
        {
            result.top += current.attr('offsetTop');
            result.left += current.attr('offsetLeft');
            current = current.offsetParent();
            if (current[0] == ancestor[0]) break;
        }
        return result;
    };


    //jQuery.getElement is an easy way to fetch jQuery encapsuled elements by selector, object or ID
    if ($.getElement)
    {
        _alert("WARNING jQuery.getElement already defined!");
    }

    $.getElement = function(obj, allowMissingField)
    {
        if (isJquery(obj))
        {
            if (!allowMissingField && !obj.exists())
            {
                _alert('programming error,' + obj + ' is an empty jQuery object');
            }
            return obj;
        }

        if (typeof (obj) == 'string')
        {
            var objId = (!obj.startsWith('#')) ? '#' + obj : obj;

            var jqElement = jQuery(objId);
            if (jqElement.exists())
            {
                return jqElement;
            }
        }
        else
        {
            var jqElement = jQuery(obj);
            if (jqElement.exists())
            {
                return jqElement;
            }
        }

        if (!allowMissingField)
        {
            _alert('getElement: programming error, cannot find any DOM element for ' + obj);
            if (DEBUG_MODE) return null;
        }
        return jQuery([]);
    }




})(jQuery);







