
if(typeof SODON == "undefined" || !SODON){ var SODON = {}; SODON.util = {}; SODON.widget = {}; SODON.example = {}; }

(function(){

    var Dom = YAHOO.util.Dom;
    var Event = YAHOO.util.Event;
    var Element = YAHOO.util.Element;
    var DDM = YAHOO.util.DragDropMgr;

    /**
     * @namespace SODON.util
     * @class Math
     */
    SODON.util.Math = {

        /**
         *
         * @method mod
         * @param {Integer} too
         * @param {Integer} sub
         */
        mod: function(too, sub){
            return (too - Math.floor(too/sub) * sub);
        },

        /**
         * 5 gesen toog 05 helberttei bolgohod ashigladag method.
         * @method fixNumber
         * @param too
         */
        fixNumber: function(too){
            if(too >= 0 && too <= 9){
                return "0" + too;
            }
            return too;
        }

    };

    /**
     * @namespace SODON.util
     * @class DateMath
     */
    SODON.util.DateMath = {

        /**
         * @property YEAR
         * @static
         * @final
         * @type String
         */
        YEAR: "Y",

        /**
         * @property MONTH
         * @static
         * @final
         * @type String
         */
        MONTH: "M",

        /**
         * @property DAY
         * @static
         * @final
         * @type String
         */
        DAY: "D",

        /**
         * @property WEEK
         * @static
         * @final
         * @type String
         */
        WEEK: "W",

        /**
         * @method add
         * @param date
         * @param field
         * @param amount
         */
        add: function(date, field, amount){
            var d = new Date(date.getTime());
            switch(field){
                case this.YEAR:
                    d.setFullYear(d.getFullYear() + amount); break;
                case this.MONTH:
                    d.setMonth(d.getMonth() + amount); break;
                case this.DAY:
                    d.setDate(d.getDate() + amount); break;
                case this.WEEK:
                    d.setDate(d.getDate() + 7*amount); break;
            }
            return d;
        },

        /**
         * @method subtract
         * @param date
         * @param field
         * @param amount
         */
        subtract: function(date, field, amount){
            return this.add(date, field, (-1)*amount);
        },

        /**
         * @method before
         * @param date
         * @param compareTo
         */
        before: function(date, compareTo){
            return date.getTime() < compareTo.getTime();
        },

        /**
         * @method before
         * @param date
         * @param compareTo
         */
        after: function(date, compareTo){
            return date.getTime() > compareTo.getTime();
        },

        /**
         * Determines whether a given date is between two other dates on the calendar.
         * @method between
         * @param {Date} date		The date to check for
         * @param {Date} dateBegin	The start of the range
         * @param {Date} dateEnd		The end of the range
         * @return {Boolean} true if the date occurs between the compared dates; false if not.
         */
        between: function(date, dateBegin, dateEnd){
            return this.after(date, dateBegin) && this.before(date, dateEnd);
        },

        /**
         * @method equals
         * @param date
         * @param compareTo
         */
        equals: function(date, compareTo){
            date = this.clearTime(date);
            compareTo = this.clearTime(compareTo);
            return date.getTime() == compareTo.getTime();
        },

        /**
         * Gets the first day of a month containing a given date.
         * @method findMonthStart
         * @param {Date}	date	The JavaScript Date used to calculate the month start
         * @return {Date}		The JavaScript Date representing the first day of the month
         */
        findMonthStart : function(date) {
            date.setDate(1);
            return date;
        },

        /**
         * Gets the last day of a month containing a given date.
         * @method findMonthEnd
         * @param {Date}	date	The JavaScript Date used to calculate the month end
         * @return {Date}		The JavaScript Date representing the last day of the month
         */
        findMonthEnd: function(date) {
            var start = this.findMonthStart(date);
            var nextMonth = this.add(start, this.MONTH, 1);
            return this.subtract(nextMonth, this.DAY, 1);
        },

        /**
         * Mongol formatand zoriulj uuniig bichsen bolno.
         * @method fixWeekday
         * @param {Integer} weekday
         * @return {Integer}
         */
        fixWeekday: function(weekday) {

            if ( weekday == 0 ) {

                weekday = 7;
            }
            return weekday-1;
        },

        /**
         * Clears the time fields from a given date, effectively setting the time to 12 noon.
         * @method clearTime
         * @param {Date}	date	The JavaScript Date for which the time fields will be cleared
         * @return {Date}		The JavaScript Date cleared of all time fields
         */
        clearTime : function(date) {
            date.setHours(0, 0, 0, 0);
            return date;
        }
    };

    /**
     *
     * @namespace SODON.util
     * @class owner
     * @param {Object} owner
     */
    SODON.util.Config = function(owner){
        this.init.apply(this, arguments);
    };

    SODON.util.Config.prototype = {

        /**
         *
         * @property owner
         * @type Object
         */
        owner: null,

        /**
         *
         * @property _DEFAULT_CONFIG
         * @type Object
         */
        _DEFAULT_CONFIG: null,

        /**
         *
         * @method init
         * @param owner
         */
        init: function(owner){
            this.owner = owner;
        },

        /**
         * @method setupConfig
         */
        setupConfig: function(){
            var key;
            for(key in this._DEFAULT_CONFIG){
            this.owner.Config[key] = this._DEFAULT_CONFIG[key];
            }
        },

        /**
         *
         * @method setConfig
         * @param {Object} config
         */
        setConfig: function(config){
            var key;
            for(key in config){
                this.owner.Config[key] = config[key];
            }
        },

        /**
         *
         * @method getConfigProperty
         * @param {String} key
         * @return Variant
         */
        getConfigProperty: function(key){
            return this.owner.Config[key];
        },

        /**
         *
         * @method setConfigProperty
         * @param {String} key
         * @param {Variant} value
         */
        setConfigProperty: function(key, value){
            this.owner.Config[key] = value;
        },

        /**
         * @description ene ni 'getConfigProperty' gedeg bichlegiig bagasgaj 'get' gej bichsen zuil.
         * @method get
         * @param {String} key
         */
        get: function(key){
            return this.getConfigProperty(key);
        },

        /**
         * @description ene ni 'setConfigProperty' gedeg bichlegiig bagasgaj 'set' gej bichsen zuil.
         * @method set
         * @param {String} key
         * @param {Variant} value
         */
        set: function(key, value){
            this.setConfigProperty(key, value);
        }

    };


    /**
     * @namespace SODON.util
     * @class Ajax
     */
    SODON.util.Ajax = function(container, method, url, config, params){

        this.init.apply(this, arguments);
    };

    SODON.util.Ajax.cfg = function(owner){
        SODON.util.Ajax.cfg.superclass.constructor.apply(this, arguments);
    }

    YAHOO.extend(SODON.util.Ajax.cfg, SODON.util.Config, {
        _DEFAULT_CONFIG: {
            ENABLE_JAVASCRIPT: true,
            TIMEOUT: 30000,
            FORM_ID: null,
            FILE_UPLOAD: false,

            START: null,
            COMPLETE: null,
            SUCCESS: null,
            FAILURE: null,
            UPLOAD: null,
            ABORT: null,

            RENDER_BEFORE: null,
            RENDER_AFTER: null
        }
    });

    SODON.util.Ajax.prototype = {

        /**
         * @description Container-ийн үүрэгтэй
         * @property oContainer
         * @type Object
         */
        oContainer: null,

        /**
         * @description Хүсэлттэй холбогдоход ашигладаг гишүүн өгөгдөл
         * @property Connect
         * @type Object
         */
        Connect: null,

        /**
         * @description Дотоод тохиргоог хадгалах үүрэгтэй гишүүн өгөгдөл
         * @property Config
         * @type Object
         */
        Config: null,

        /**
         * @description Тохиргоог хариуцагч класстай холбогдоход ашигладаг гишүүн өгөгдөл
         * @property cfg
         * @type Object
         */
        cfg: null,

        /**
         * @description
         * @property request
         * @type Object
         */
        request: null,

        /**
         * @description
         * @method init
         * @param {String} container
         * @param {String} method
         * @param {String} url
         * @param {Object} config
         * @param {Object} params
         */
        init: function(container, method, url, config, params) {

            var self = this;

            this.oContainer = Dom.get(container);
            if(this.oContainer != null){

                method = method.toUpperCase();

                this.Config = {};
                this.cfg = new SODON.util.Ajax.cfg(this);
                this.cfg.setupConfig();

                if(config != null){
                    this.cfg.setConfig(config);
                }

                var Connect = YAHOO.util.Connect;

                if(method == "POST" && this.cfg.getConfigProperty("FORM_ID") != null){
                    Connect.setForm(this.cfg.getConfigProperty("FORM_ID"), this.cfg.getConfigProperty("FILE_UPLOAD"));
                }

                var callback = {
                    customevents: {
                        onStart: function(type, args) {
                            if ( self.cfg.getConfigProperty("START") != null && YAHOO.lang.isFunction(self.cfg.getConfigProperty("START")) ) {
                                self.cfg.getConfigProperty("START")(type, args);
                            }
                        },
                        onComplete: function(type, args) {
                            if ( self.cfg.getConfigProperty("COMPLETE") != null && YAHOO.lang.isFunction(self.cfg.getConfigProperty("COMPLETE")) ) {
                                self.cfg.getConfigProperty("COMPLETE")(type, args);
                            }
                        },
                        onSuccess: function(type, args) {
                            if ( self.cfg.getConfigProperty("RENDER_BEFORE") != null && YAHOO.lang.isFunction(self.cfg.getConfigProperty("RENDER_BEFORE")) ) {
                                self.cfg.getConfigProperty("RENDER_BEFORE")(type, args);
                            }
                            args[0].argument[0].innerHTML = args[0].responseText;
                            if ( self.cfg.getConfigProperty("RENDER_AFTER") != null && YAHOO.lang.isFunction(self.cfg.getConfigProperty("RENDER_AFTER")) ) {
                                self.cfg.getConfigProperty("RENDER_AFTER")(type, args);
                            }
                            self.evalJavascript(args[0].argument[0]);
                        },
                        onFailure: function(type, args) {
                            args[0].argument[0].innerHTML += "Transaction " + args[0].tId + ", type: " + type + " fired, status: " + args[0].status + ", statusText: " + args[0].statusText;
                        },
                        onAbort: function(type, args) {
                            args[0].argument[0].innerHTML += "Transaction " + args[0].tId + ", " + type + " fired.";
                        }
                    },

                    argument: [self.oContainer],

                    timeout: self.cfg.getConfigProperty("TIMEOUT")
                };

                Connect.asyncRequest(method, url, callback, params);

            }
        },

        /**
         * @description
         * @method evalJavascript
         */
        evalJavascript: function(htmlElement){
            var javascriptElements = htmlElement.getElementsByTagName("script");
            var i = 0;
            while(i < javascriptElements.length){
                eval(javascriptElements[i].innerHTML);
                i++;
            }
        }

    };

    /**
     * @namespace SODON.util
     * @class ImageInfo
     * @param {String | HTMLElement} el
     * @param {Object} attr
     */
    SODON.util.ImageInfo = function(attr){
        SODON.util.ImageInfo.superclass.constructor.call(this, document.createElement("img"), attr);
    };

    YAHOO.extend(SODON.util.ImageInfo, Element, {

        init: function(el, attr){
            SODON.util.ImageInfo.superclass.init.call(this, el, attr);
        },

        initAttributes: function(attr){
            SODON.util.ImageInfo.superclass.initAttributes.call(this, attr);

            this.set("src", attr["src"]);

            var method = null;
            if(attr["imgload"] != null){
                method = attr["imgload"];
            }
            else{
                method = function(){
                    //here is code
                };
            }
            if(attr["data"] != null){
                Event.on(this.get('element'), "load", method, attr["data"]);
            }
            else{
                Event.on(this.get('element'), "load", method);
            }

            /*Event.on(this.get('element'), "abort", function(){
                alert("abort");
            });

            if(this.get('element').complete){
                alert("yes");
            }
            else{
                alert("no");
            }*/

        },

        getWidth: function(){
            return this.get("width");
        },

        getHeight: function(){
            return this.get("height");
        }

    });


    /**
     * @description Тодорхой хүрээний дотор элементүүдийг чирч байрлуулахад ашигладаг.
     * @namespace SODON.widget
     * @class DDList
     * @param {String || HTMLElement} id
     * @param {String || HTMLElement} sGroup
     * @param {Object} config
     */
    SODON.widget.DDList = function(id, sGroup, config){

        SODON.widget.DDList.superclass.constructor.call(this, id, sGroup, config);

        var el = this.getDragEl();

        Dom.setStyle(el, "opacity", 0.7); // The proxy is slightly transparent

        this.goingUp = false;
        this.lastX = 0;
        this.lastY = 0;
    };


    YAHOO.extend(SODON.widget.DDList, YAHOO.util.DDProxy, {

        /**
         * element-iig chirch duusahad.
         * @method endDrag
         * @param {Event} e
         */
        endDrag: function(e){

            var srcEl = this.getEl();
            var proxyEl = this.getDragEl();

            // Show the proxy element and animate it to the src element's location
            Dom.setStyle(proxyEl, "visibility", "");
            var a = new YAHOO.util.Motion(
                proxyEl, {
                    points: {
                        to: Dom.getXY(srcEl)
                    }
                },
                0.2,
                YAHOO.util.Easing.easeOut
            )
            var proxyId = proxyEl.id;
            var srcId = srcEl.id;

            // Hide the proxy and show the source element when finished with the animation
            a.onComplete.subscribe(function() {
                    Dom.setStyle(proxyId, "visibility", "hidden");
                    Dom.setStyle(srcId, "visibility", "");
                });
            a.animate();
        },

        /**
         * proxy element-ee chireh uildel hiih bolgond.
         * @method onDrag
         * @param {Event} e
         */
        onDrag: function(e){

            // Keep track of the direction of the drag for use during onDragOver
            var y = Event.getPageY(e);

            if(y < this.lastY){
                this.goingUp = true;
            }
            else if(y > this.lastY){
                this.goingUp = false;
            }

            this.lastY = y;
        }

    });

    /**
     * @description Body-g burhdeg container. Uuniig ihevchlen tusgai zoriulaltiin flash-iig site
     * deeguuree togluulahad ashigladag.
     * @namespace SODON.widget
     * @class FillBodyContainer
     * @constructor
     * @param {HTMLElement | String} container
     * @param {Object} config
     */
    SODON.widget.FillBodyContainer = function(container, config) {
        this.init.apply(this, arguments);
    };

    /**
     * Scroll-iin cofiguration iig beltgedeg class.
     * @namespace SODON.widget.FillBodyContainer
     * @class cfg
     * @param {Object} owner
     */
    SODON.widget.FillBodyContainer.cfg = function(owner) {
        SODON.widget.FillBodyContainer.cfg.superclass.constructor.apply(this, arguments);
    };

    YAHOO.extend(SODON.widget.FillBodyContainer.cfg, SODON.util.Config, {

        _DEFAULT_CONFIG: {

            /**
             * @description
             * @propery direction
             * @type String
             */
            direction: "horizontal"
        }

    });

    SODON.widget.FillBodyContainer.prototype = {

        /**
         * @property container
         * @private
         * @type Object
         */
        container: null,

        /**
         * @property Config
         * @private
         * @type Object
         */
        Config: null,

        /**
         * @description tohirgoonuudiig hadgaldag property
         * @property cfg
         * @type Object
         */
        cfg: null,

        /**
         * @description baiguulagch method.
         * @method init
         * @param {String} container
         * @param {Object} config
         */
        init: function(container, config) {

            var self = this;

            if ( container == null ) alert("SODON.widget.FillBodyContainer javascript ажиллах боломжгүй. Учир нь container гишүүн өгөгдөлд утга байхгүй байна.");
            this.container = Dom.get(container);

            this.Config = {};
            this.cfg = new SODON.widget.FillBodyContainer.cfg(this);

            this.cfg.setupConfig();
            if ( config != null ) {
                this.cfg.setConfig(config);
            }

            // for containerOut

            // for initialize settings
            var containerOut = this.cfg.getConfigProperty("containerOut");
            var containerWidth = this.cfg.getConfigProperty("containerWidth");

            Dom.setStyle(containerOut, "width", Dom.getDocumentWidth() + "px");
            Dom.setStyle(containerOut, "height", Dom.getDocumentHeight() + "px");
            Dom.setStyle(containerOut, "left", "0px");
            Dom.setStyle(containerOut, "top", "0px");
            Dom.setStyle(containerOut, "display", "none");

            Dom.setStyle(this.container, "display", "none");
            Dom.setStyle(this.container, "left", ((Dom.getDocumentWidth() - containerWidth) / 2) + "px");

            // end of initialize settings

            // for init events
            this.initEvents();
        },

        /**
         * @description
         * @method show
         */
        show: function() {

            var containerOut = this.cfg.getConfigProperty("containerOut");
            var containerTop = this.cfg.getConfigProperty("containerTop");

            Dom.setStyle(containerOut, "display", "");
            Dom.setStyle(this.container, "top", (Dom.getDocumentScrollTop() + containerTop) + "px");
            Dom.setStyle(this.container, "display", "");
        },

        /**
         * @description
         * @method hide
         */
        hide: function() {

            var containerOut = this.cfg.getConfigProperty("containerOut");

            Dom.setStyle(containerOut, "display", "none");
            Dom.setStyle(this.container, "display", "none");
        },

        /**
         * @description init events
         * @method initEvents
         */
        initEvents: function() {

            var self = this;
            var closeButton = this.cfg.getConfigProperty("closeButton");

            // for close button
            Event.on(closeButton, "click", function(e) {

                self.hide();
            });
            // end of close button
        }
    };

    SODON.util.Log = {

        /**
         * @description Log hevlegch method.
         * @method render
         * @param {String} value
         */
        render: function(value) {

            var container = Dom.get("log");
            if (container != null) {
                container.value += value + "\n";
            }
        }
    }

})();





