﻿///<reference path="../TESCO.js" />
///<reference path="../event.js" />
///<reference path="../eventManager.js" />
///<reference path="../exception.js" />
///<reference path="../node.js" />
///<reference path="../position.js" />

TESCO.$("sites.retail.UI.Tooltip").loader = (function() {
	
    //  public static
    this.NAME = "TESCO.sites.retail.UI.Tooltip.loader";
    
    //  private static
	var _loaded = false;
	var NODE = TESCO.system.DOM.node;
	var _tooltip;

	//  constructor
	function _constructor() {
		var _container = new TESCO.sites.retail.UI.InfoContainer("Tooltip", "tooltip abs hidden");
		NODE.addClassName(_container.content, "smallText");
		this.content = _container.content;
        TESCO.system.event.manager.call(this, "mouseover");
        //  wait for the body
        TESCO.system.event.document.addEventListener("load",
            function() {
                document.body.appendChild(_container.container);
                /*@cc_on
                if (_container.container.iframe)
                    document.body.appendChild(_container.container.iframe.rect);
                @*/
                _loaded = true;
                TESCO.system.event.attach(document.body, "mouseover",
                    function(e) {
                        _tooltip.dispatchEvent("mouseover", e);
                    }, false
                );
            }
        );

        _constructor.base.constructor.call(this, _container.container, TESCO.system.browser.ie6);

	    return this;
    }
    _constructor.extend(TESCO.UI.Rectangle.Position);

    //  loaded accessor
    _constructor.prototype.loaded = function() {
        return _loaded;
    }

    //  return instance
    return (_tooltip = new _constructor());
})();

/* 
	Abstract class which extends the TESCO.sites.retail.UI.Tooltip.loader object.
	Calls the load method, but does not implement it.

*/

TESCO.sites.retail.UI.Tooltip = (function() {

    //  private static
	var NODE = TESCO.system.DOM.node;
	var CONFIG = TESCO.sites.Configuration;

	function _position(e) {	//  work out final position
        var _offset = CONFIG.tooltips.offset;
        var _scroll = TESCO.UI.document.getScrollXY();
		var _winSize = TESCO.UI.document.getWindowSize();
		var _x = e.x;
		if ((_winSize.innerWidth / 2) < (e.x - _scroll[0])) {
		    //  right half of screen
		    _x -= (_offset + this.rect.offsetWidth);
		} else {
		    //  left half of screen
		    _x += _offset;
		}
		var _y = e.y;
		if ((_winSize.innerHeight / 2) < (e.y - _scroll[1])) {
		    //  bottom half of screen
		    _y -= (_offset + this.rect.offsetHeight);
		} else {
		    //  top half of screen
		    _y += _offset;
	    }
		this.moveTo(_x, _y);
		/*@cc_on
        if (this.iframe) {
            this.iframe.resize(
				this.rect.offsetWidth - (CONFIG.infoContainer.left + CONFIG.infoContainer.right), 
				this.rect.offsetHeight - (CONFIG.infoContainer.top + CONFIG.infoContainer.bottom)
			);
			this.iframe.moveBy(CONFIG.infoContainer.left, CONFIG.infoContainer.top);
		}
        @*/
	}

	//  constructor
	function _constructor() {
        this.timer;
		this.hideTimer;
	    var _self = this;
	    _self.addEventListener("mouseover",
	        function(e) {
	            _self.toggle(e);
	        }
	    );
	    return this;
    }
    TESCO.sites.retail.UI.Tooltip.loader.extend(_constructor);

    _constructor.prototype.NAME = "TESCO.sites.retail.UI.Tooltip";
    
    //  public methods
    //  augment position show
	_constructor.prototype.show = function(e, content) {
		NODE.addClassName(this.rect, _constructor.key);
	    //	append content
	    this.content.appendChild(content);
		this.raise();
		this.activate();
		_position.call(this, e);
		//  call base show
        _constructor.base.show.call(this);
	}

	//  augment position hide
	_constructor.prototype.hide = function() {
		this.deactivate();
		//  call base hide
		_constructor.base.hide.call(this);
		NODE.removeChildNodes(this.content);
	}

	_constructor.prototype.toggle = function(e) {
        if (this.loaded()) {
			if (this.active()) {
				this.hide();
            }
            if (this.timer) {
                this.timer = clearTimeout(this.timer);
            }
            var _e = { x : e.pageX, y : e.pageY, target : e.target }
            var _self = this;
            this.timer = setTimeout(
                function() {
                    //  abstract method call, must be implemented in derived class
                    _self.load(_e);
                }, CONFIG.tooltips.showDelay
            );
        }
    }

    //  return constructor as function pointer
    return _constructor;
})();

/*

	Plain tooltips can be added by adding the class ‘plaintooltip’, a title
	attribute and an id to any element. If you add a class of ‘plaintooltip’
	to an element but omit the id or title attributes, or leave the title
	blank a Javascript exception will be raised, to prevent you displaying
	an empty box.
    Removes the title attribute from the element.

*/

TESCO.sites.retail.UI.Tooltip.Plain = (function() {

	//  private static
	var _cache = new TESCO.system.Cache();
	var _active = false;
	var _timer;
    var CONFIG = TESCO.sites.Configuration;

    function _assemble(content) {
        var _p = document.createElement("p");
        TESCO.system.DOM.node.setTextValue(_p, content);
        return _p;
    }

    //  constructor
	function _constructor() {
	    _constructor.base.constructor.call(this);
	    return this;
    }
    _constructor.extend(TESCO.sites.retail.UI.Tooltip);

    _constructor.prototype.NAME = "TESCO.sites.retail.UI.Tooltip.Plain";
    
	_constructor.prototype.activate = function() {
		_active = true;
	}

	_constructor.prototype.deactivate = function() {
		_active = false;
	}

	_constructor.prototype.active = function() {
		return _active;
	}

    //  must return node
    _constructor.prototype.load = function(e) {
        //  check if a tooltip is required
        if (TESCO.system.DOM.node.hasClassName(e.target, "plaintooltip")) {
            var _key = e.target.id;
            if (_key) {
				TESCO.sites.retail.UI.Tooltip.key = _key.split("-")[0];
				var _att;
                var _content = _cache.getItem(_key);
                if (e.target.getAttribute("title")) {
					_att = "title";
				} else if (e.target.getAttribute("alt")) {
					_att = "alt";
				} else {
				    _txt = TESCO.system.DOM.node.getTextValue(e.target);
				}
                if (!_content) {
					_content = e.target[_att] || _txt;
                    if (!_content) {
                        throw new Error(this.NAME + ": '" + e.target + "' " + _att + " attribute is required");
                    }
                    _content = _assemble(_content);
                    _cache.setItem(_key, _content);
                }
                e.target.setAttribute("title", "");
                this.show(e, _content);
            } else {
                throw new Error(this.NAME + ": '" + e.target + "' id attribute is required");
            }
        }
    }

    //  show tooltip for 5 seconds
 	_constructor.prototype.show = function(e, content) {
 	    var _self = this;
       clearTimeout(_timer);
       _constructor.base.show.call(this, e, content);
       _timer = setTimeout(
		    function() {
			    //  call base hide
			    _constructor.base.hide.call(_self);
		    }, CONFIG.tooltips.duration
	    );
	}

	//  augment position hide
	//  hide tooltip immediately
	_constructor.prototype.hide = function() {
	    clearTimeout(_timer);
        _constructor.base.hide.call(this);
	}
	
    //  construct instance
    new _constructor();
})();

/* 
	Rich tooltips, which may include extra html like links and piccies, can
	be generated by adding a class of ‘richtooltip’ and an id to any element.
	Add the content in the locale.js file.
	
*/

TESCO.sites.retail.UI.Tooltip.Rich = (function() {

	var _active = false;

    //  constructor
	function _constructor() {
	    _constructor.base.constructor.call(this);
		var _self = this;
		TESCO.system.event.attach(this.rect, "mouseover",
			function(e) {
				e.stopEvent();
				clearTimeout(_self.hideTimer);
			}, false
		);
	    return this;
    }
    _constructor.extend(TESCO.sites.retail.UI.Tooltip);
    
    _constructor.prototype.NAME = "TESCO.sites.retail.UI.Tooltip.Rich";
    
	_constructor.prototype.activate = function() {
		_active = true;
	}

	_constructor.prototype.deactivate = function() {
		_active = false;
	}

	_constructor.prototype.active = function() {
		return _active;
	}

    //  public method
    //  must return node
    _constructor.prototype.load = function(e) {
        //  check if a tooltip is required
        if (TESCO.system.DOM.node.hasClassName(e.target, "richtooltip")) {
            var _key = e.target.id;
            if (_key) {
				TESCO.sites.retail.UI.Tooltip.key = _key.split("-")[0];
                var _content = TESCO.locale.tooltips[e.target.id];
                e.target.setAttribute("title", "");
                if (_content && !_active) {
                    this.show(e, _content());
                } else {
                    throw new Error(this.NAME + ": TESCO.locale.tooltips['" + e.target.id + "'] is undefined");
                }
            } else {
                throw new Error(this.NAME + ": '" + e.target + "' id attribute is required");
            }
        } 
    }

	//  augment position hide
	_constructor.prototype.hide = function() {
		var _self = this;
		this.hideTimer = setTimeout(
			function() {
				//  call base hide
				_constructor.base.hide.call(_self);
			}, 1000
		);
	}
    //  construct instance
    new _constructor();
})();
