"use strict";

/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: false,
bitwise: true, regexp: true, strict: true, newcap: true, immed: true */

/*global dojo, dijit */

/**
 * create HTML tooltips from normal tooltips 
 * @constructor
 * @author milodorn
 * @version 1.0
 * 
 * TODO comments / revise
 * 
 */
function CFTooltip() {
    
    var THIS = this;
    
    /**
     * dojo queries for tooltip elements
     * @memberOf CFTooltip
     * @type Array
     * @return {Array} 
     */
    this.elements = [];
    
    this.ofsX = 20;
    
    this.ofsY = 20;
    
    this.cssClass = 'cfTooltip';
    
    this.maxWidth = 400;
    
    this.maxHeight = 300;
    
    this.mousemoveHandle = null;
    
    this.mouseCoords = { x: 0, y: 0 };
    
    this.mouseWatch = null;
    
    this.viewPort = {};
    
    this.tooltipHtml = '%%%label%%%';
    
    this.activeTooltip = null;
    
    /**
     * add dojo queries for tooltip elements, use '*' for every element with 'title' and/or 'alt'
     * tag (for images only)
     * @memberOf CFTooltip
     * @type Function
     * @return {undefined}
     * @param {Array} els 
     */
    this.addTooltip = function (els) {
        els = dojo.isArray(els) ? els : [els];
        dojo.forEach(els, function (item) {
            THIS.elements.push(item);
        });
    };
    
    /**
     * enable CF tooltip
     * @memberOf CFTooltip
     * @type Function
     * @return {undefined}
     * @param {HTMLElement} el 
     */
    this.enableTooltip = function (el) {
        var alt, // alt property value
        cftitle, // CF title property value
        els, // queried elements
        title; // title property value
        
        dojo.forEach(dojo.query(el), function (el) {
            alt = dojo.attr(el, 'alt');
            cftitle = dojo.attr(el, 'cfTitle');
            title = dojo.attr(el, 'title');
            cftitle = cftitle ? cftitle : (title && (title !== '') ? title : alt);
            if (!el.cfTooltip && cftitle) {
                el.cfTooltip = new CFTooltipBox({
                    element: el,
                    label: cftitle,
                    cftooltip: THIS
                });
                dojo.removeAttr(el, 'title'); // clear TITLE to prevent showing it by browser
                dojo.attr(el, 'alt', ''); // clear ALT to prevent showing it by browser
            }
        });
    };
    
    this.getViewPort = function () {
        THIS.viewPort = dijit.getViewport();
    };

    /**
     * tooltip main initialization
     * @memberOf CFTooltip
     * @type Function
     * @return {undefined} 
     */
    this.init = function () {
        dojo.require("dijit._base.place");
        dojo.connect(dojo.doc, "onmousemove", THIS.storeMouseCoords);
        dojo.addOnLoad(THIS.onload);
    };
    
    /**
     * tooltip onload initialization
     * @memberOf CFTooltip
     * @type Function
     * @return {undefined} 
     */
    this.onload = function () {
        dojo.forEach(THIS.elements, THIS.enableTooltip);
        dojo.connect(window, "onresize", THIS.getViewPort);
        THIS.getViewPort();
    };
    
    this.storeMouseCoords = function (ev) {
        var px, py;
        ev = ev || window.event;
        if (ev.pageX || ev.pageY) {
            px = ev.pageX;
            py = ev.pageY;
        } else {
            px = ev.clientX + dojo.body().scrollLeft - dojo.body().clientLeft;
            py = ev.clientY + dojo.body().scrollTop - dojo.body().clientTop;
        }
        THIS.mouseCoords.x = px;
        THIS.mouseCoords.y = py;
        if (THIS.mouseWatch) {
            THIS.mouseWatch();
        }
    }
    
}

function CFTooltipBox(settings) {
    
    var THIS = this;
    
    this.element = null;
    
    this.label = null;
    
    this.tel = null;
    
    this.cftooltip = null;
    
    this.showTooltip = function () {
        if (THIS.cftooltip.activeTooltip) {
            THIS.cftooltip.activeTooltip.hideTooltip();
        }
        if (THIS.tel) {
            dojo.destroy(THIS.tel);
        }
        THIS.tel = dojo.create('div', null, dojo.body());
        THIS.tel.style.position = 'absolute';
        THIS.tel.style.zIndex = 9999999999;
        THIS.placeBase();
        THIS.tel.innerHTML = THIS.cftooltip.tooltipHtml.replace('%%%label%%%', THIS.label);
        THIS.fixSize();
        THIS.cftooltip.mouseWatch = THIS.place;
        THIS.place();
        THIS.tel.className = THIS.cftooltip.cssClass;
        THIS.cftooltip.activeTooltip = THIS;
    };
    
    this.fixSize = function () {
        var c = dojo.coords(THIS.tel);
        THIS.tel.style.width = (c.w > THIS.cftooltip.maxWidth ? THIS.cftooltip.maxWidth : c.w) + 'px';
        THIS.tel.style.height = (c.h > THIS.cftooltip.maxHeight ? THIS.cftooltip.maxHeight : c.h) + 'px';
    };
    
    this.place = function () {
        var px = THIS.cftooltip.mouseCoords.x + THIS.cftooltip.ofsX;
        var py = THIS.cftooltip.mouseCoords.y + THIS.cftooltip.ofsY;
        THIS.tel.style.left =  px + 'px';
        THIS.tel.style.top = py + 'px';
        var c = dojo.coords(THIS.tel);
        if ((c.x + c.w) > THIS.cftooltip.viewPort.w) {
            px = THIS.cftooltip.mouseCoords.x - THIS.cftooltip.ofsX - c.w;
            THIS.tel.style.left =  px + 'px';
        }
        if ((c.y + c.h) > THIS.cftooltip.viewPort.h) {
            py = THIS.cftooltip.mouseCoords.y - THIS.cftooltip.ofsY - c.h;
            THIS.tel.style.top =  py + 'px';
        }
    };
    
    this.placeBase = function () {
        THIS.tel.style.left = 0;
        THIS.tel.style.top = 0;
    };
    
    this.hideTooltip = function () {
        if (THIS.tel) {
            dojo.destroy(THIS.tel);
        }
        THIS.cftooltip.mouseWatch = null;
    };
    
    return function () {
        THIS.element = dojo.byId(settings.element);
        if (!THIS.element) {
            return;
        }
        THIS.label = settings.label;
        THIS.cftooltip = settings.cftooltip;
        dojo.connect(THIS.element, 'onmouseover', THIS.showTooltip);
        dojo.connect(THIS.element, 'onmouseout', THIS.hideTooltip);
        dojo.connect(THIS.element, 'onmousedown', THIS.hideTooltip);
    }();

}