/**
 * defaultHint v1
 * Date: 2010-11-30 10:00:00
 *
 * If "elementHint" is not specified, "elementHint" and "showAsterisk" is taken from the element label
 * Example of using DefaultHint in QSF2:
 * $params = array(
 *     array('name', 'Name:', true),
 *     array('emailOrPhone', 'Email:', false),
 *     array('comments', 'Your Message:'),  // By default showAsterisk = false
 * );
 * OR
 * $params = array('name', 'emailOrPhone', 'comments'); // Take "elementHint" and "showAsterisk" from element label
 * OR
 * $params = array('name' => 'Name:', 'emailOrPhone' => false, 'comments' => 'Your Message:');
 * $this->doc->addScript('js/defaultHint.js', array(), 'defaultHint');
 * $this->doc->addInitFunction('defaultHint.init', array($params));
 *
 * Also you can call "defaultHint.init" without parameters to collect elements and labels from form
 */

DefaultHint = {
    requiredClassName: 'required',

    isIE: false,
    optionsType: false,
    elements: null,
    _tmpL: null,

    init: function (options)
    {
        DefaultHint.optionsType = Object.prototype.toString.call(options);
        if ('[object String]' == DefaultHint.optionsType) {
            DefaultHint.collectElements(options);
            DefaultHint.optionsType = Object.prototype.toString.call(DefaultHint.elements);
        } else if ('[object Array]' == DefaultHint.optionsType || '[object Object]' == DefaultHint.optionsType) {
            DefaultHint.elements = options;
        } else {
            throw 'Invalid parameter options type: "' + DefaultHint.optionsType + '" given in DefaultHint.init()';
        }
        DefaultHint.prepare();
    },

    prepare: function ()
    {
        DefaultHint.isIE = (navigator.appName == "Microsoft Internet Explorer");
        for (k in DefaultHint.elements) {
            DefaultHint.set(k);
        }
        return true;
    },

    set: function (id)
    {
        var elementId = false;
        var elementHint = false;
        var showAsterisk = false;
        if ('[object Array]' == DefaultHint.optionsType) {
            if ('object' == typeof DefaultHint.elements[id]) {
                var elementId = DefaultHint.elements[id][0] || false;
                var elementHint = DefaultHint.elements[id][1] || false;
                var showAsterisk = DefaultHint.elements[id][2] || false;
            } else if ('string' == typeof DefaultHint.elements[id]) {
                var elementId = DefaultHint.elements[id] || false;
                var elementHint = false;
                var showAsterisk = false;
            }
        } else if ('[object Object]' == DefaultHint.optionsType) {
            var elementId = id;
            var elementHint = DefaultHint.elements[id]
            var showAsterisk = false;
        } else {
            throw 'Invalid parameter id: "' + id + '" given in DefaultHint.set()';
        }
        if (!(el = document.getElementById(elementId))
            || !DefaultHint.isElement(el)
        ) {
            throw 'Invalid element: "'+elementId+'" given in DefaultHint.set()';
        }
        if (!elementHint) {
            if (null === DefaultHint._tmpL && el.form) {
                DefaultHint._tmpL = {};
                DefaultHint._tmpE = [];
                DefaultHint.buildTree(el.form);
                delete DefaultHint._tmpE;
            }
            if (DefaultHint._tmpL[elementId]) {
                var elementHint = DefaultHint._tmpL[elementId].innerHTML || elementId;
                if (DefaultHint._tmpL[elementId].classList) {
                    var showAsterisk = DefaultHint._tmpL[elementId].classList.contains(DefaultHint.requiredClassName);
                } else {
                    var showAsterisk = (DefaultHint._tmpL[elementId].className.indexOf(DefaultHint.requiredClassName) > -1);
                }
            }
        }
        var div = document.createElement('div');
        div.id = elementId + '-hint';
        div.className = 'element-default-hint';
        if (showAsterisk || false) {
            var span = document.createElement('span');
            span.className = 'asterisk';
            span.appendChild(document.createTextNode('*'));
            div.appendChild(span);
        }
        div.appendChild(document.createTextNode(elementHint));
        if (typeof(el.value) != 'undefined' && el.value > '') {
            div.style.display = 'none';
        }
        div.onclick = DefaultHint.onHintClick;
        div.onmousedown = DefaultHint.onHintMouseDown;
        el.onfocus = DefaultHint.onElementFocus;
        el.onblur  = DefaultHint.onElementBlur;
        div.belongTo = el;
        el.defaultHint = div;
        el.parentNode.insertBefore(div, el.nextSibling);
        return true;
    },

    buildTree: function(node)
    {
        if (node.hasChildNodes()) {
            for (var i = 0; i < node.childNodes.length; i++) {
                if (1 == node.childNodes[i].nodeType) {
                    if (DefaultHint.isLabel(node.childNodes[i])) {
                        DefaultHint._tmpL[node.childNodes[i].htmlFor] = node.childNodes[i];
                    } else if (DefaultHint.isElement(node.childNodes[i])) {
                        DefaultHint._tmpE.push(node.childNodes[i].id);
                    }
                    if (node.childNodes[i].hasChildNodes) {
                        DefaultHint.buildTree(node.childNodes[i]);
                    }
                }
            }
        }
    },

    collectElements: function(formId)
    {
        var form = document.getElementById(formId);
        if (!form || !form.childNodes) {
            throw 'Container with id: "' + formId + '" not found';
        }
        DefaultHint.elements = [];
        DefaultHint._tmpE = [];
        DefaultHint._tmpL = {};
        DefaultHint.buildTree(form);
        for (k in DefaultHint._tmpE) {
            var elementId = DefaultHint._tmpE[k];
            if (DefaultHint._tmpL[elementId]) {
                var elementHint = DefaultHint._tmpL[elementId].innerHTML || elementId;
                if (DefaultHint._tmpL[elementId].classList) {
                    var showAsterisk = DefaultHint._tmpL[elementId].classList.contains(DefaultHint.requiredClassName);
                } else {
                    var showAsterisk = (DefaultHint._tmpL[elementId].className.indexOf(DefaultHint.requiredClassName) > -1);
                }
            } else {
                var elementHint = elementId;
                var showAsterisk = false;
            }
            DefaultHint.elements.push([elementId, elementHint, showAsterisk]);
        }
        delete DefaultHint._tmpE;
    },

    isLabel: function(hEl)
    {
        return (hEl.tagName && 'label' == hEl.tagName.toLowerCase() && hEl.htmlFor);
    },

    isElement: function(hEl)
    {
        if (hEl.tagName && 'input' == hEl.tagName.toLowerCase() && hEl.type) {
            return ('text' == hEl.type || 'password' == hEl.type);
        } else {
            return (hEl.tagName && 'textarea' == hEl.tagName.toLowerCase());
        }
    },

    onHintClick: function ()
    {
        this.belongTo.focus();
        return false;
    },

    onHintMouseDown: function()
    {
        if (DefaultHint.isIE) {
            var el = this.belongTo;
            setTimeout(function() { el.focus(); }, 1);
        } else {
            this.belongTo.focus();
        }
        return false;
    },

    onElementFocus: function ()
    {
        this.defaultHint.style.display = 'none';
        return false;
    },

    onElementBlur: function ()
    {
        if ('' == this.value) {
            this.defaultHint.style.display = 'block';
        }
        return false;
    }
}
