///<reference path="../TESCO.js" />
///<reference path="../system/event.js" />
///<reference path="../system/event.manager.js" />
///<reference path="../system/exception.js" />
///<reference path="../system/DOM.node.js" />

TESCO.UI.Collapse = (function() {

    // private static
    ///#region
    var _registary = [];
    var NODE = TESCO.system.DOM.node;
    var CONFIG = TESCO.sites.Configuration;
	///#endregion
	
	//	private instance
	///#region    
    function _stop(collapse, fields) {
        clearInterval(fields.timer);
        fields.toggling = false;
        this.dispatchEvent("complete", fields);
    }
    
    function _toggle(collapse, settings) {
		//	toggles state
        var _fields = _registary[this.index()];
			_fields.position.css.overflow = "hidden";		
        if (_fields.collapsed !== collapse) {
			if (_fields.toggling) {
				_stop.call(this, collapse, _fields);
			}
			_fields.collapsed = collapse;
			_fields.toggling = true;
            settings = settings || {};
			//  set initial variables
			var _interval = settings.interval || CONFIG.collapse.interval;
			var _steps = settings.steps || CONFIG.collapse.steps;
			var _blender = settings.blender || (collapse ? CONFIG.collapse.blender.collapse : CONFIG.collapse.blender.expand);
			var _step = 0;
			var _self = this;
			if (!collapse) {
				_fields.position.css.display = _fields.display;
			} else {
				_fields.position.height = _fields.position.rect.offsetHeight;
			}
			var _end = collapse ? 0 : _fields.position.rect.scrollHeight;
			//  start blending
			_fields.timer = setInterval(
				function() {
            		_fields.position.resizeH(_blender(_fields.position.height, _end, _steps, _step));
            		if ((_step++ >= _steps) || (!collapse && _fields.position.height >= _end) || (collapse && _fields.position.height <= _end)) {
            			_self.finish(collapse);
            		}
				}, _interval
			);
        } else {
            this.dispatchEvent("complete", _fields);
        }
    }
    ///#endregion

    function _constructor(container, collapsed, collapseClass) {

        TESCO.system.event.manager.call(this, "complete");
        //	check if the container already in the container set
        var _L;
        for (var i = 0, _L = _registary.length; i < _L; i++) {
            if (_registary[i].container === container) {
				return _registary[i].self;
			}
        }
		
		//	the collapsible element may be within the container
        var _rectangle = NODE.getElementsByClassName(container, (collapseClass ? collapseClass : "collapsible"));
			_rectangle = (_rectangle) ? _rectangle[0] : container	//	use the container if an element to collapse is not found within the container
        var _collapsed = !!collapsed;
        
        var _fields = _registary[_L] = {
			"container" : container, 
			"display" : NODE.getStyle(container, "display"),
			"position" : new TESCO.UI.Rectangle.Position(_rectangle),
			"collapsed" : _collapsed,
			"timer" : null,
			"self" : this,
			"toggling" : false
		};
        
        if (_collapsed) {
            _fields.position.css.height = 0 + TESCO.system.browser.px;
            _fields.position.css.display = "none";
            _fields.position.css.overflow = "hidden";
        } else {
            _fields.position.css.height = "";
        }
        
        this.index = function() {
			return _L;
        }
        return this;
    }

	///#region
	//	public instance
    _constructor.prototype.NAME = "TESCO.UI.Collapse";
    
    _constructor.prototype.collapsed = function() {
		return _registary[this.index()].collapsed;
    }
    
    _constructor.prototype.toggle = function(settings) {
        _toggle.call(this, !this.collapsed(), settings);
    }

    _constructor.prototype.expand = function(settings) {
        _toggle.call(this, false, settings);
    }
    
    _constructor.prototype.collapse = function(settings) {
        _toggle.call(this, true, settings);
    }
    
    _constructor.prototype.finish = function(collapse) {
        var _fields = _registary[this.index()];
        if (collapse) {
			_fields.position.css.display = "none";
        } else {
            _fields.position.css.display = _fields.display;
            _fields.position.css.height = "";
            _fields.position.css.overflow = "";
        }
        _stop.call(this, collapse, _fields);
    }
    ///#endregion

    return _constructor;
})();

TESCO.UI.Collapse.Tbody = (function() {

    function _constructor(container, collapsed, collapseClass) {
        /*@cc_on
        this.collapsed = collapsed;
        @*/
        _constructor.base.constructor.apply(this, arguments);
        return this;
    }
    _constructor.extend(TESCO.UI.Collapse);

	///#region
	//	public instance
    _constructor.prototype.NAME = "TESCO.UI.Collapse.Tbody";
    
    /*@cc_on
    _constructor.prototype.expand = function() {
        this.finish(false);
        this.collapsed = false;
    }
    
    _constructor.prototype.toggle = function() {
        this.collapsed ? this.expand() : this.collapse();
    }
    
    _constructor.prototype.collapse = function() {
        this.finish(true);
        this.collapsed = true;
    }
    @*/
    ///#endregion

    return _constructor;
})();

TESCO.UI.Collapse.Section = (function() {

    function _constructor(container, trigger, collapsed, attributes) {
		var _container;
        if (container.nodeType == "1") {
            _container = container;
        } else {
            _container = document.getElementById(container);
        }
        
		var _trigger;
        if (trigger.nodeType == "1") {
            _trigger = trigger;
        } else {
            _trigger = document.getElementById(trigger);
        }
        _constructor.base.constructor.call(this, _container, collapsed, null);
        var _self = this;
        TESCO.system.event.attach(trigger, "click",
			function(e) {
			    _self.toggle();
			    var _collapsed = _self.collapsed();
			    var img = _trigger.getElementsByTagName("img")[0];
			    if (!_collapsed && attributes.collapseImg) {
			        img.src = attributes.collapseImg;
			        if (attributes.expandAlt) {
			            img.alt = attributes.expandAlt;
			        }
			    }
			    if (_collapsed && attributes.expandImg) {
			        img.src = attributes.expandImg;
			        if (attributes.collapseAlt) {
			            img.alt = attributes.collapseAlt;
			        }
			    }
			    if (attributes.preventDefault) {
			        e.stopEvent();
			    }

			    /*for Links*/
			    var link = _trigger;
			    var newState = _collapsed;
			    if (!newState && attributes.collapseLink) {			        
			        link.firstChild.nodeValue = attributes.collapseLink;
			        if (attributes.expandLinkAlt) {
			            link.title = attributes.expandLinkAlt;
			        }
			    }

			    if (newState && attributes.expandLink) {
			        link.firstChild.nodeValue = attributes.expandLink;
			        if (attributes.collapseLinkAlt) {
			            link.title = attributes.collapseLinkAlt;
			        }
			    }

			}, false
		);
        return this;
    }
    _constructor.extend(TESCO.UI.Collapse);

    //	public instance
    _constructor.prototype.NAME = "TESCO.UI.Collapse.Section";

    return _constructor;
})();
