﻿
    // #region Core
    // ************

        // #region String Prototyping
        // **************************

        String.prototype.padLeft = function (length, character)
        {
            var _this = this;
            try
            {
                while (_this.length < length)
                    _this = character + _this;
                return _this;
            }
            finally
            {
                _this = null;
            }
        };

        String.prototype.padRight = function (length, character)
        {
            var _this = this;
            try
            {
                while (_this.length < length)
                    _this = _this + character;
                return _this;
            }
            finally
            {
                _this = this;
            }
        };

        String.prototype.trim = function ()
        {
            var _this = this;
            try
            {
                return _this.replace(/^\s+|\s+$/g, "");
            }
            finally
            {
                _this = this;
            }
        }

        // #endregion

        // #region Date Prototyping
        // ************************

        Date.prototype.toString = function (format)
        {
            var _this = this;
            try
            {
                var 
                    _monthArray = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"),
                    _dayArray = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"),
                    _year = new String(_this.getFullYear()),
                    _yearShort = new String(Math.floor((_this.getFullYear() / 100 - Math.floor(_this.getFullYear() / 100)) * 100)),
                    _month = new String(_this.getMonth() + 1),
                    _day = new String(_this.getDay()),
                    _date = new String(_this.getDate()),
                    _hour = new String(_this.getHours()),
                    _hour12 = (parseInt(_hour) > 12 ? new String(parseInt(_hour) % 12) : _hour),
                    _minute = new String(_this.getMinutes()),
                    _second = new String(_this.getSeconds()),
                    _millisecond = new String(_this.getMilliseconds()),
                    _returnString = "";

                if (typeof format == "undefined")
                    format = "dd/MM/yyyy HH:mm:ss.fff";

                _returnString = new String(format);

                _returnString = _returnString.replace(/fff/g, "$01");
                _returnString = _returnString.replace(/ff/g, "$02");
                _returnString = _returnString.replace(/f/g, "$03");
                _returnString = _returnString.replace(/ss/g, "$04");
                _returnString = _returnString.replace(/s/g, "$05");
                _returnString = _returnString.replace(/mm/g, "$06");
                _returnString = _returnString.replace(/m/g, "$07");
                _returnString = _returnString.replace(/hh/g, "$08");
                _returnString = _returnString.replace(/h/g, "$09");
                _returnString = _returnString.replace(/HH/g, "$10");
                _returnString = _returnString.replace(/H/g, "$11");
                _returnString = _returnString.replace(/dddd/g, "$12");
                _returnString = _returnString.replace(/ddd/g, "$13");
                _returnString = _returnString.replace(/dd/g, "$14");
                _returnString = _returnString.replace(/d/g, "$15");
                _returnString = _returnString.replace(/MMMM/g, "$16");
                _returnString = _returnString.replace(/MMM/g, "$17");
                _returnString = _returnString.replace(/MM/g, "$18");
                _returnString = _returnString.replace(/M/g, "$19");
                _returnString = _returnString.replace(/yyyy/g, "$20");
                _returnString = _returnString.replace(/yyy/g, "$21");
                _returnString = _returnString.replace(/yy/g, "$22");
                _returnString = _returnString.replace(/y/g, "$23");

                _returnString = _returnString.replace(/\$01/g, Math.floor(parseInt(_millisecond)));
                _returnString = _returnString.replace(/\$02/g, Math.floor(parseInt(_millisecond) / 10));
                _returnString = _returnString.replace(/\$03/g, Math.floor(parseInt(_millisecond) / 100));

                _returnString = _returnString.replace(/\$04/g, _second.padLeft(2, "0"));
                _returnString = _returnString.replace(/\$05/g, _second);

                _returnString = _returnString.replace(/\$06/g, _minute.padLeft(2, "0"));
                _returnString = _returnString.replace(/\$07/g, _minute);

                _returnString = _returnString.replace(/\$08/g, _hour12.padLeft(2, "0"));
                _returnString = _returnString.replace(/\$09/g, _hour12);

                _returnString = _returnString.replace(/\$10/g, _hour.padLeft(2, "0"));
                _returnString = _returnString.replace(/\$11/g, _hour);

                _returnString = _returnString.replace(/\$12/g, _dayArray[parseInt(_day)]);
                _returnString = _returnString.replace(/\$13/g, _dayArray[parseInt(_day)].substr(0, 3));
                _returnString = _returnString.replace(/\$14/g, _date.padLeft(2, "0"));
                _returnString = _returnString.replace(/\$15/g, _date);

                _returnString = _returnString.replace(/\$16/g, _monthArray[parseInt(_month) - 1]);
                _returnString = _returnString.replace(/\$17/g, _monthArray[parseInt(_month) - 1].substr(0, 3));
                _returnString = _returnString.replace(/\$18/g, _month.padLeft(2, "0"));
                _returnString = _returnString.replace(/\$19/g, _month);

                _returnString = _returnString.replace(/\$20/g, _year);
                _returnString = _returnString.replace(/\$21/g, _year);
                _returnString = _returnString.replace(/\$22/g, _yearShort);
                _returnString = _returnString.replace(/\$23/g, _yearShort.padLeft(2, "0"));

                return _returnString;
            }
            finally
            {
                _this = null;
            }
        };

        Date.fromBritishDateString = function (dateString)
        {
            var _theDateString = new String(dateString).trim();
            try
            {
                var 
                    _date = "",
                    _time = "",
                    _year = 0,
                    _month = 0,
                    _day = 1,
                    _hour = 0,
                    _minute = 0,
                    _second = 0,
                    _millisecond = 0;

                if (_theDateString.indexOf(" ") > -1)
                {
                    _date = _theDateString.split(" ")[0];
                    _time = _theDateString.split(" ")[1];
                }
                else
                    _date = _theDateString;

                if (_date != "")
                {
                    _year = parseInt(_date.split("/")[2]);
                    _month = parseInt(_date.split("/")[1]) - 1;
                    _day = parseInt(_date.split("/")[0]);
                }

                if (_time != "")
                {
                    if (_time.indexOf(".") > -1)
                    {
                        _millisecond = parseInt(_time.split(".")[1]);
                        _time = _time.split(".")[0];
                    }

                    _hour = _time.split(":")[0];
                    _minute = _time.split(":")[1];
                    _second = _time.split(":")[2];
                }

                var _returnDate = new Date(_year, _month, _day, _hour, _minute, _second);
                _returnDate.setMilliseconds(_millisecond);
                return _returnDate;
            }
            catch (_e)
            {
                throw _e;
            }
            return null;
        };

        Date.fromXMLDateString = function (dateString)
        {
            var _theDateString = new String(dateString).trim();
            try
            {
                var 
                    _date = "",
                    _time = "",
                    _year = 0,
                    _month = 0,
                    _day = 1,
                    _hour = 0,
                    _minute = 0,
                    _second = 0;

                if (_theDateString.indexOf("T") > -1)
                {
                    _date = _theDateString.split("T")[0];
                    _time = _theDateString.split("T")[1];
                }
                else
                    _date = _theDateString;

                if (_date != "")
                {
                    _year = parseInt(_date.split("-")[0]);
                    _month = parseInt(_date.split("-")[1]) - 1;
                    _day = parseInt(_date.split("-")[2]);
                }

                if (_time != "")
                {
                    if (_time.indexOf("+") > -1)
                        _time = _time.split("+")[0];

                    _hour = _time.split(":")[0];
                    _minute = _time.split(":")[1];
                    _second = _time.split(":")[2];
                }

                return new Date(_year, _month, _day, _hour, _minute, _second);
            }
            catch (_e)
            {
                throw _e;
            }
            return null;
        };

        // #endregion

        // #region Function Prototyping
        // ****************************

        Function.prototype._inherits = function (baseClass)
        {
            var _prop = null;

            try
            {
                if (this == baseClass)
                    throw "Cannot derive from self";

                for (_prop in baseClass.prototype)
                {
                    if (typeof (baseClass.prototype[_prop]) == "function" && !this.prototype[_prop] && _prop != "base")
                        this.prototype[_prop] = baseClass.prototype[_prop];
                }

                if (!this.prototype.base)
                {
                    this.prototype.base = new Object();
                    this.prototype.baseCount = 0;
                }

                this.prototype.base[this.prototype.baseCount] = baseClass;
                this.prototype.baseCount++;
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _prop = null;
            }

        };

        Function.prototype._constructBase = function ()
        {
            if (this.prototype && this.prototype.base && typeof this.prototype.baseCount != "undefined")
            {
                for (var _i = 0; _i < this.prototype.baseCount; _i++)
                {
                    if (this.prototype.base[_i])
                    {
                        if (arguments.length >= _i + 1 && typeof arguments[_i + 1] != "undefined" && arguments[_i + 1] != null)
                            this.prototype.base[_i].apply(arguments[0], arguments[_i + 1]);
                        else
                            this.prototype.base[_i].apply(arguments[0]);
                    }
                }
            }
        };

        Function.prototype._callBase = function (objectContext, functionName)
        {
            var 
                _args = new Array(),
                _caller = arguments.callee.caller,
                _i;

            try
            {
                if (this.prototype && this.prototype.base && typeof this.prototype.baseCount != "undefined")
                {
                    if (!functionName)
                    {
                        var _prop = null;

                        try
                        {
                            for (_prop in this.prototype)
                            {
                                if (this.prototype[_prop] == _caller)
                                {
                                    functionName = _prop;
                                    for (_i = 0; _i < _caller.arguments.length; _i++)
                                        _args[_i] = _caller.arguments[_i];
                                    break;
                                }
                            }
                        }
                        finally
                        {
                            _prop = null;
                        }

                    }

                    if (functionName)
                    {
                        if (!_args)
                        {
                            for (_i = 2; _i < arguments.length; _i++)
                                _args[_i - 2] = arguments[_i];
                        }

                        for (_i = this.prototype.baseCount - 1; _i >= 0; _i--)
                        {
                            if (this.prototype.base[_i] && this.prototype.base[_i].prototype && this.prototype.base[_i].prototype[functionName])
                                return this.prototype.base[_i].prototype[functionName].apply(objectContext, _args); // Check
                        }
                    }
                }
            }
            finally
            {
                _caller = null;
            }
        };

        // #endregion

    // #endregion

    // #region indigo
    // **************

    var indigo = {};
    indigo._construct = function ()
    {

        var _namespace = "indigo";

        function objectName(name)
        {
            return "[" + _namespace + "." + name + "]";
        }

        // #region indigo.object
        // *********************

        function _object()
        {
        }
        _object.prototype.dispose = function ()
        {
        };
        _object.prototype.toString = function ()
        {
            return objectName("object");
        };
        this.object = _object;

        // #endregion

        // #region indigo.event
        // ********************

        function _event(ev)
        {
            var 
                _this = this;

            try
            {
                _this.originalEvent = ev;
                _this.keyCode = ev.which ? ev.which : ev.keyCode;
                _this.clientX = ev.clientX;
                _this.clientY = ev.clientY;
                _this.sourceElement = ev.srcElement ? ev.srcElement : ev.target;
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _this = null;
            }
        }
        _event._inherits(_object);
        _event.prototype.cancelBubble = function ()
        {
            this.originalEvent.cancelBubble = true;
            if (this.originalEvent.stopPropagation)
                this.originalEvent.stopPropagation();
        };
        this.event = _event;

        // #endregion

        // #region indigo.collection
        // *************************

        function _collection()
        {
            _collection._constructBase(this);
            this.count = 0;
            this.items = new Object();
        }
        _collection._inherits(_object);
        _collection.prototype.add = function (o)
        {
            this.addAt(this.count, o);
            return o;
        };
        _collection.prototype.addAt = function (index, o)
        {
            for (var _i = this.count; _i > index; _i--)
            {
                this.items[_i] = this.items[_i - 1];
            }
            this.items[index] = o;
            this.count++;
            return o;
        };
        _collection.prototype.clear = function ()
        {
            for (var _i = 0; _i < this.count; _i++)
            {
                if (this.items[_i].dispose)
                    this.items[_i].dispose();

                this.items[_i] = null;

                this.count = 0;
            }
        };
        _collection.prototype.contains = function (o)
        {
            return this.indexOf(o) > -1;
        };
        _collection.prototype.dispose = function ()
        {
            for (var _i = 0; _i < this.count; _i++)
                this.removeAt(_i);
            _collection._callBase(this);
        };
        _collection.prototype.each = function (fn)
        {
            for (var _i = 0; _i < this.count; _i++)
                fn.call(this.items[_i], _i);
        };
        _collection.prototype.indexOf = function (o)
        {
            for (var _i = 0; _i < this.count; _i++)
            {
                if (this.items[_i] == o)
                    return _i;
            }
            return -1;
        };
        _collection.prototype.remove = function (o)
        {
            for (var _i = 0; _i < this.count; _i++)
            {
                if (this.items[_i] == o)
                {
                    this.removeAt(_i);
                    break;
                }
            }
        };
        _collection.prototype.removeAt = function (index)
        {
            if (this.items[index].dispose)
                this.items[index].dispose();

            this.items[index] = null;

            for (var _i = index; _i < this.count - 1; _i++)
                this.items[_i] = this.items[_i + 1];

            this.items[this.count - 1] = null;
            this.count--;
        };
        _collection.prototype.toString = function ()
        {
            return objectName("collection");
        };
        this.collection = _collection;

        // #endregion

        // #region Object Event Handler

        // #region indigo.objectEventFunction
        // **********************************

        function _objectEventFunction(f)
        {
            _objectEventFunction._constructBase(this);
            this.f = f;
        }
        _objectEventFunction._inherits(_object);
        _objectEventFunction.prototype.toString = function ()
        {
            return objectName("objectEventFunction");
        };

        // #endregion

        // #region indigo.objectEventFunctionCollection
        // ********************************************

        function _objectEventFunctionCollection()
        {
            _objectEventFunctionCollection._constructBase(this);
        }
        _objectEventFunctionCollection._inherits(_collection);
        _objectEventFunctionCollection.prototype.toString = function ()
        {
            return objectName("objectEventFunctionCollection");
        };

        // #endregion

        // #region indigo.objectEvent
        // **************************

        function _objectEvent(eventName)
        {
            _objectEvent._constructBase(this);
            this.eventName = eventName;
            this.objectEventFunctions = new _objectEventFunctionCollection();
        }
        _objectEvent._inherits(_object);
        _objectEvent.prototype.toString = function ()
        {
            return objectName("objectEvent");
        };

        // #endregion

        // #region indigo.objectEventCollection
        // ************************************

        function _objectEventCollection()
        {
            _objectEventCollection._constructBase(this);
        }
        _objectEventCollection._inherits(_collection);
        _objectEventCollection.prototype.toString = function ()
        {
            return objectName("objectEventCollection");
        };

        // #endregion

        // #region indigo.objectEventHandlerObject
        // ***************************************

        function _objectEventHandlerObject(o)
        {
            _objectEventHandlerObject._constructBase(this);
            this.o = o;
            this.objectEvents = new _objectEventCollection();
        }
        _objectEventHandlerObject._inherits(_object);
        _objectEventHandlerObject.prototype.toString = function ()
        {
            return objectName("objectEventHandlerObject");
        };

        // #endregion

        // #region indigo.objectEventHandlerObjectCollection
        // *************************************************

        function _objectEventHandlerObjectCollection()
        {
            _objectEventHandlerObjectCollection._constructBase(this);
        }
        _objectEventHandlerObjectCollection._inherits(_collection);
        _objectEventHandlerObjectCollection.prototype.toString = function ()
        {
            return objectName("objectEventHandlerObjectCollection");
        };

        // #endregion

        // #region indigo.objectEventHandler
        // *********************************

        function _objectEventHandler()
        {
            _objectEventHandler._constructBase(this);
            this.objects = new _objectEventHandlerObjectCollection();
        }
        _objectEventHandler._inherits(_object);
        _objectEventHandler.prototype.attach = function (o, eventName, f)
        {
            var 
                _this = this,
                _foundEvent = false,
                _foundFunction = false;

            try
            {
                if (o != null)
                {
                    for (var _i = 0; _i < _this.objects.count; _i++)
                    {
                        if (_this.objects.items[_i].o == o)
                        {
                            for (var _j = 0; _j <= _this.objects.items[_i].objectEvents.count; _j++)
                            {
                                if (_this.objects.items[_i].objectEvents.items[_j].eventName == eventName)
                                {
                                    _foundEvent = true;
                                    for (var _k = 0; _k < _this.objects.items[_i].objectEvents.items[_j].objectEventFunctions.count; _k++)
                                    {
                                        if (_this.objects.items[_i].objectEvents.items[_j].objectEventFunctions.items[_k].f == f)
                                        {
                                            _foundFunction = true;
                                            break;
                                        }
                                    }
                                    if (!_foundFunction)
                                    {
                                        _this.objects.items[_i].objectEvents.items[_j].objectEventFunctions.add(new _objectEventFunction(f));
                                    }
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    if (!_foundEvent)
                    {
                        throw "Event \"" + eventName + "\" not registered for object \"" + o.toString() + "\"";
                    }
                }
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _this = null;
                _foundEvent = null;
                _foundFunction = null;
            }
        };
        _objectEventHandler.prototype.call = function (o, eventName, args)
        {
            var _this = this;
            try
            {
                for (var _i = 0; _i < _this.objects.count; _i++)
                {
                    if (_this.objects.items[_i].o == o)
                    {
                        for (var _j = 0; _j < _this.objects.items[_i].objectEvents.count; _j++)
                        {
                            if (_this.objects.items[_i].objectEvents.items[_j].eventName == eventName)
                            {
                                for (var _k = 0; _k < _this.objects.items[_i].objectEvents.items[_j].objectEventFunctions.count; _k++)
                                    _this.objects.items[_i].objectEvents.items[_j].objectEventFunctions.items[_k].f(o, args);
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _this = null;
            }
        };
        _objectEventHandler.prototype.register = function (o, eventName)
        {
            var 
                    _this = this,
                    _foundObject = false;

            try
            {
                for (var _i = 0; _i < _this.objects.count; _i++)
                {
                    if (_this.objects.items[_i].o == o)
                    {
                        _foundObject = true;
                        _this.objects.items[_i].objectEvents.add(new _objectEvent(eventName));
                        break;
                    }
                }
                if (!_foundObject)
                    _this.objects.add(new _objectEventHandlerObject(o)).objectEvents.add(new _objectEvent(eventName));
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _this = null;
                _foundObject = null;
            }
        };
        _objectEventHandler.prototype.detach = function (o, eventName, f)
        {
            var 
                    _this = this;

            try
            {
                if (o != null)
                {
                    for (var _i = 0; _i < _this.objects.count; _i++)
                    {
                        if (_this.objects.items[_i].o == o)
                        {
                            for (var _j = 0; _j < _this.objects.items[_i].objectEvents.count; _j++)
                            {
                                if (_this.objects.items[_i].objectEvents.items[_j].eventName == eventName)
                                {
                                    for (var _k = 0; _k < _this.objects.items[_i].objectEvents.items[_j].objectEventFunctions.count; _k++)
                                    {
                                        if (_this.objects.items[_i].objectEvents.items[_j].objectEventFunctions.items[_k].f == f)
                                            _this.objects.items[_i].objectEvents.items[_j].objectEventFunctions.removeAt(_k);
                                    }
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _this = null;
            }
        };
        _objectEventHandler.prototype.toString = function ()
        {
            return objectName("objectEventHandler");
        };
        this.objectEventHandler = new _objectEventHandler();

        // #endregion

        // #endregion

        // #region Element Event Handler

        // #region indigo.elementEventFunction
        // ***********************************

        function _elementEventFunction(f)
        {
            _elementEventFunction._constructBase(this);
            this.f = f;
        }
        _elementEventFunction._inherits(_object);
        _elementEventFunction.prototype.toString = function ()
        {
            return objectName("elementEventFunction");
        };

        // #endregion

        // #region indigo.elementEventFunctionCollection
        // *********************************************

        function _elementEventFunctionCollection()
        {
            _elementEventFunctionCollection._constructBase(this);
        }
        _elementEventFunctionCollection._inherits(_collection);
        _elementEventFunctionCollection.prototype.create = function (f)
        {
            var _eef = new _elementEventFunction(f);
            _elementEventFunctionCollection.prototype.add.call(this, _eef);
            return _eef;
        };
        _elementEventFunctionCollection.prototype.toString = function ()
        {
            return objectName("elementEventFunctionCollection");
        };

        // #endregion

        // #region indigo.elementEvent
        // ***************************

        function _elementEvent(el, eventName)
        {
            _elementEvent._constructBase(this);

            var 
                    _this = this;

            _this.el = el;
            _this.eventName = eventName;
            _this.functions = new _elementEventFunctionCollection();

            function _handleEvent(_e)
            {
                var _returnVal = true, _localReturnVal = true;
                for (var i = 0; i < _this.functions.count; i++)
                {
                    _localReturnVal = _this.functions.items[i].f(_e);
                    if (typeof _localReturnVal != "undefined" && _localReturnVal == false)
                        _returnVal = false;
                }
                return _returnVal;
            }

            if (el.attachEvent)
                el.attachEvent("on" + _this.eventName, function (e) { var ev = e ? e : event; return _handleEvent(new _event(ev)); });
            else if (el.addEventListener)
                el.addEventListener(_this.eventName, function (e) { var ev = e ? e : event; return _handleEvent(new _event(ev)); }, false);
        }
        _elementEvent._inherits(_object);
        _elementEvent.prototype.toString = function ()
        {
            return objectName("elementEvent");
        };

        // #endregion

        // #region indigo.elementEventCollection
        // *************************************

        function _elementEventCollection()
        {
            _elementEventCollection._constructBase(this);
        }
        _elementEventCollection._inherits(_collection);
        _elementEventCollection.prototype.create = function (el, eventName)
        {
            var _eev = new _elementEvent(el, eventName);
            _elementEventCollection.prototype.add.call(this, _eev);
            return _eev;
        };
        _elementEventCollection.prototype.toString = function ()
        {
            return objectName("elementEventCollection");
        };

        // #endregion

        // #region indigo.elementEventHandlerElement
        // ******************************************

        function _elementEventHandlerElement(el)
        {
            _elementEventHandlerElement._constructBase(this);
            this.el = el;
            this.events = new _elementEventCollection();
        }
        _elementEventHandlerElement._inherits(_collection);
        _elementEventHandlerElement.prototype.toString = function ()
        {
            return objectName("elementEventHandlerElement");
        };

        // #endregion

        // #region indigo.elementEventCollectionElementCollection
        // ******************************************************

        function _elementEventCollectionElementCollection()
        {
            _elementEventCollectionElementCollection._constructBase(this);
        }
        _elementEventCollectionElementCollection._inherits(_collection);
        _elementEventCollectionElementCollection.prototype.create = function (el)
        {
            var _eehe = new _elementEventHandlerElement(el);
            _elementEventCollectionElementCollection.prototype.add.call(this, _eehe);
            return _eehe;
        };
        _elementEventCollectionElementCollection.prototype.toString = function ()
        {
            return objectName("elementEventCollectionElementCollection");
        };

        // #endregion

        // #region indigo.elementEventHandler
        // ***********************************

        function _elementEventHandler()
        {
            _elementEventHandler._constructBase(this);
            this.elements = new _elementEventCollectionElementCollection();
        }
        _elementEventHandler._inherits(_object);
        _elementEventHandler.prototype.attach = function (el, eventName, f)
        {
            var 
                    _this = this,
                    _foundElement = false,
                    _foundEvent = false,
                    _foundFunction = false;

            try
            {
                if (el != null)
                {
                    for (var _i = 0; _i < _this.elements.count; _i++)
                    {
                        if (_this.elements.items[_i].el == el)
                        {
                            _foundElement = true;
                            for (var _j = 0; _j < _this.elements.items[_i].events.count; _j++)
                            {
                                if (_this.elements.items[_i].events.items[_j].eventName == eventName)
                                {
                                    _foundEvent = true;
                                    for (var _k = 0; _k < _this.elements.items[_i].events.items[_j].functions.count; _k++)
                                    {
                                        if (_this.elements.items[_i].events.items[_j].functions.items[_k].f == f)
                                        {
                                            _foundFunction = true;
                                            break;
                                        }
                                    }
                                    if (!_foundFunction)
                                    {
                                        _this.elements.items[_i].events.items[_j].functions.add(new _elementEventFunction(f));
                                    }
                                    break;
                                }
                            }
                            if (!_foundEvent)
                                _this.elements.items[_i].events.create(el, eventName).functions.create(f);
                            break;
                        }
                    }
                    if (!_foundElement)
                        _this.elements.create(el).events.create(el, eventName).functions.create(f);
                }
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _this = null;
                _foundElement = null;
                _foundEvent = null;
                _foundFunction = null;
            }
        };
        _elementEventHandler.prototype.detach = function (el, eventName, f)
        {
            var 
                _this = this;

            try
            {
                if (el != null)
                {
                    for (var _i = 0; _i < _this.elements.count; _i++)
                    {
                        if (_this.elements.items[_i].el == el)
                        {
                            for (var _j = 0; _j < _this.elements.items[_i].events.count; _j++)
                            {
                                if (_this.elements.items[_i].events.items[_j].eventName == eventName)
                                {
                                    for (var _k = 0; _k < _this.elements.items[_i].events.items[_j].functions.count; _k++)
                                    {
                                        if (_this.elements.items[_i].events.items[_j].functions.items[_k].f == f)
                                        {
                                            _this.elements.items[_i].events.items[_j].functions.removeAt(_k);
                                            break;
                                        }
                                    }
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _this = null;
            }
        };
        _elementEventHandler.prototype.toString = function ()
        {
            return objectName("elementEventHandler");
        };
        this.elementEventHandler = new _elementEventHandler();

        // #endregion

        // #endregion

        // indigo.nameSpaceManager
        // ***********************
        function _nameSpaceManager()
        {
            _nameSpaceManager._constructBase(this);

            var _this = this;
            _this.head = null;
        }
        _nameSpaceManager._inherits(_collection);
        _nameSpaceManager.prototype.include = function (nameSpaceName)
        {
            var 
                _this = this,
                _head = document.getElementsByTagName("head"),
                _script = null,
                _found = false;

            try
            {
                if (_head && _head[0])
                {
                    _this.head = _head[0];
                    for (var _i = 0; _i < _this.head.childNodes.length; _i++)
                    {
                        _script = _this.head.childNodes[_i];
                        if (_script.nodeName.toUpperCase() == "SCRIPT")
                        {
                            var _src = _script.getAttribute("src");
                            if (_src.toLowerCase() == "javascript/" + nameSpaceName.toLowerCase() + ".js")
                                _found = true;
                        }
                    }

                    if (!_found)
                    {
                        _script = document.createElement("script");
                        _script.setAttribute("type", "text/javascript");
                        _script.setAttribute("src", "javascript/" + nameSpaceName.toLowerCase() + ".js");
                        _this.head.appendChild(_script);
                    }
                }
            }
            catch (_e)
            {
                throw _e;
            }
            finally
            {
                _head = null;
                _script = null;
            }
        };
        _nameSpaceManager.prototype.toString = function ()
        {
            return objectName("namespaceManager");
        };
        this.nameSpaceManager = new _nameSpaceManager();

        // indigo.elementHelper
        // ********************
        function _elementHelper()
        {
            _elementHelper._constructBase(this);
        }
        _elementHelper._inherits(indigo.object);
        _elementHelper.prototype.left = function (element)
        {
            if (!element) return 0;
            var _curleft = 0;
            if (element.offsetParent)
                while (true)
                {
                    _curleft += element.offsetLeft;
                    if (!element.offsetParent)
                        break;
                    element = element.offsetParent;
                }
            else if (element.x)
                _curleft += element.x;
            return _curleft;
        };
        _elementHelper.prototype.height = function (element)
        {
            return element.clientHeight;
        };
        _elementHelper.prototype.relativeLeft = function (element)
        {
            if (!element) return 0;
            var _curleft = 0;
            if (element.offsetParent)
                _curleft += element.offsetLeft;
            return _curleft;
        };
        _elementHelper.prototype.top = function (element)
        {
            if (!element) return 0;
            var _curtop = 0;
            if (element.offsetParent)
                while (true)
                {
                    _curtop += element.offsetTop;
                    if (!element.offsetParent)
                        break;
                    element = element.offsetParent;
                }
            else if (element.y)
                _curtop += element.y;
            return _curtop;
        };
        _elementHelper.prototype.toString = function ()
        {
            return objectName("elementHelper");
        };
        _elementHelper.prototype.width = function (element)
        {
            return element.clientWidth;
        };
        _elementHelper.prototype.preventSelect = function (element)
        {
            if (element.style.MozUserSelect !== undefined)
                element.style.MozUserSelect = "none";
            else if (element.style.webkitUserSelect !== undefined)
                element.style.webkitUserSelect = "none";

            element.setAttribute("unselectable", "on");
        };
        this.elementHelper = new _elementHelper();

        // indigo.windowHelper
        // *******************
        function _windowHelper()
        {
            _windowHelper._constructBase(this);
        }
        _windowHelper._inherits(indigo.object);
        _windowHelper.prototype.getLeft = function ()
        {
            var 
                _returnVal = 0,
                _window = window,
                _parentWindow = null,
                _iframes = null,
                _iframe = null,
                _i;

            try
            {
                while (_window.parent && _window.parent != _window)
                {
                    _parentWindow = _window.parent;
                    _iframes = _parentWindow.document.getElementsByTagName("iframe");
                    for (_i = 0; _i < _iframes.length; _i++)
                    {
                        if (_iframes[_i].contentWindow == window)
                        {
                            _returnVal += indigo.elementHelper.left(_iframes[_i]);
                            break;
                        }
                    }
                    _window = _parentWindow;
                }
            }
            finally
            {
                _window = null;
                _parentWindow = null;
                _iframes = null;
                _iframe = null;
            }

            return _returnVal;
        };
        _windowHelper.prototype.getTop = function ()
        {
            var 
                _returnVal = 0,
                _window = window,
                _parentWindow = null,
                _iframes = null,
                _iframe = null,
                _i;

            try
            {
                while (_window.parent && _window.parent != _window)
                {
                    _parentWindow = _window.parent;
                    _iframes = _parentWindow.document.getElementsByTagName("iframe");
                    for (_i = 0; _i < _iframes.length; _i++)
                    {
                        if (_iframes[_i].contentWindow == window)
                        {
                            _returnVal += indigo.elementHelper.top(_iframes[_i]);
                            break;
                        }
                    }
                    _window = _parentWindow;
                }
            }
            finally
            {
                _window = null;
                _parentWindow = null;
                _iframes = null;
                _iframe = null;
            }

            return _returnVal;
        };
        _windowHelper.prototype.getScrollXY = function ()
        {
            var scrOfX = 0, scrOfY = 0;
            if (typeof (window.pageYOffset) == 'number')
            {
                //Netscape compliant
                scrOfY = window.pageYOffset;
                scrOfX = window.pageXOffset;
            }
            else if (document.body && (document.body.scrollLeft || document.body.scrollTop))
            {
                //DOM compliant
                scrOfY = document.body.scrollTop;
                scrOfX = document.body.scrollLeft;
            }
            else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop))
            {
                //IE6 standards compliant mode
                scrOfY = document.documentElement.scrollTop;
                scrOfX = document.documentElement.scrollLeft;
            }
            return { x: scrOfX, y: scrOfY };
        }
        _windowHelper.prototype.toString = function ()
        {
            return objectName("windowHelper");
        };
        this.windowHelper = new _windowHelper();

    };
    indigo._construct();

    // #endregion

