﻿var DomTool =
{

/*** color ***/
isValidColor: function(col)
{
    try
    {
        var r1 = /^[0-9a-f]{3}$/i;
        var r2 = /^[0-9a-f]{6}$/i;
        
        return r1.test(col) || r2.test(col);
    }
    catch(ex)
    {
        return false;
    }
},

hexDigits: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"],

randomColor: function()
{
    var res = "";
    for (var i = 0; i < 6; ++i)
    {
        var idx = MathTool.intRandom(1000) % 16;
        res += DomTool.hexDigits[idx];
    }
    
    return res;
},

makeFullColor: function(col)
{
    var res = null;
    
    try
    {
        col = col.toString().toLowerCase();
        
        if (!DomTool.isValidColor(col)) throw 0;
        
        if (col.length == 3)
        {
            var col2 = "";
            for (var i = 0; i < 3; ++i)
            {
                var ch = col.charAt(i);
                col2 += "" + ch + ch;
            }
            
            col = col2;            
        }
        
        return col;
    }
    catch(ex)
    {
        return null;
    }
},

/*** misc ***/
clearSelection: function()
{
    if(document.selection && document.selection.empty)
    {
        document.selection.empty();
    }
    else if(window.getSelection)
    {
        var sel = window.getSelection();
        if (sel && sel.removeAllRanges) sel.removeAllRanges();
    }
},

assignProps: function(el, obj)
{
    var childs = el.childNodes;
    if (!childs) return;
    for (var i = 0; i < childs.length; ++i)
    {
        var chld = childs[i];
        if (chld.nodeType != 1) continue; // not an ELEMENT
        
        var id = chld.id;        
        if (id) obj[id.toString()] = chld;
        chld._obj = obj;
        
        DomTool.assignProps(chld, obj);
    }
},

assignGlobalProps: function(el)
{
    if (!el) el = DomTool.getBody();
    
    var childs = el.childNodes;
    for (var i = 0; i < childs.length; ++i)
    {
        var ch = childs[i];
        if (ch.nodeType != 1) continue;
        
        var id = ch.id;
        
        if (id)
        {
            if (id.startsWith("g_"))
            {
                window[id] = ch;
            }
        }

        DomTool.assignGlobalProps(ch);
    }    
},

/*** Coordinates & Sizes ***/
pxToEmRatio: null, // 1px = ?em
emToPxRatio: null, // 1em = ?px

pxToEm: function(px, addSuffix)
{
    var res = px * DomTool.getPxToEmRatio();
    res = Math.floor(res * 10000) / 10000;
    if (addSuffix) res += "em";
    return res;
},

emToPx: function(em, addSuffix)
{
    var res = em * DomTool.getEmToPxRatio();
    res = Math.floor(res * 10000) / 10000;
    if (addSuffix) res += "px";
    return res;
},

emAddPx: function(em, dpx, addSuffix)
{
    var px = DomTool.emToPx(em);
    px += dpx;
    return DomTool.pxToEm(px, addSuffix);
},

getPxToEmRatio: function()
{
    if (DomTool.pxToEmRatio) return DomTool.pxToEmRatio;
    DomTool.retrieveRatios();
    return DomTool.pxToEmRatio;
},

getEmToPxRatio: function()
{
    if (DomTool.emToPxRatio) return DomTool.emToPxRatio;
    DomTool.retrieveRatios();
    return DomTool.emToPxRatio;
},

retrieveRatios: function()
{
    var d = DomTool.makeDiv(null, null);
    with (d.style)
    {
        position = "absolute";
        width = "1000em";
        height = "1em";
        left = "0em";
        top = "0em";
    }
    DomTool.getBody().appendChild(d);
    var r = DomTool.getRect(d);
    DomTool.getBody().removeChild(d);
    
    DomTool.pxToEmRatio = 1000 / r.w;
    DomTool.emToPxRatio = r.w / 1000;
},

inRect: function (pt, rect)
{
    var res =
        pt.x >= rect.x1 && 
        pt.x <= rect.x2 &&
        pt.y >= rect.y1 &&
        pt.y <= rect.y2;
        
    return res;
},

getCoords: function(elem)
{
    if(typeof(elem.offsetParent) != 'undefined')
    {
        for(var posX = 0, posY = 0; elem; elem = elem.offsetParent)
        {
            posX += elem.offsetLeft;
            posY += elem.offsetTop;
        }
        
        return {x: posX, y: posY};
    }
    else
    {
        return {x: elem.x, y: elem.y};
    }
},

getSizes: function(elem)
{
    var width = elem.offsetWidth;
    var height = elem.offsetHeight;
    
    return {w: width, h: height};
},

makeBar: function(x1, y1, w, h, suffix)
{
    var x2 = x1 + w;
    var y2 = y1 + h;
    return DomTool.makeRect(x1, y1, x2, y2, suffix);
},

makeRect: function(x1, y1, x2, y2, suffix)
{
    var s = suffix ? suffix : "";

    var xr2 = Math.max(x1, x2);
    var xr1 = Math.min(x1, x2);
    
    var yr2 = Math.max(y1, y2);
    var yr1 = Math.min(y1, y2);
    
    var res = 
    {
        x1: xr1 + s,
        y1: yr1 + s,
        x2: xr2 + s,
        y2: yr2 + s,
        w: (xr2 - xr1) + s,
        h: (yr2 - yr1) + s
    };
    
    return res;
},

ofsRect: function(r, dx, dy)
{
    r.x1 += dx;
    r.x2 += dx;
    r.y1 += dy;
    r.y2 += dy;
},

getRect: function(elem)
{
    var pos = DomTool.getCoords(elem);
    var sizes = DomTool.getSizes(elem);
    
    var res = {
        x1: pos.x,
        y1: pos.y,
        x2: pos.x + sizes.w,
        y2: pos.y + sizes.h,
        w: sizes.w,
        h: sizes.h};
        
    return res;
},

getRectById: function(id)
{
    return DomTool.getRect(DomTool.getElem(id));
},

moveElem: function(elem, x, y)
{
    if (x || x === 0)
    {
        var xs = "" + x;
        if (xs.isInt()) xs += "px";
        elem.style.left = xs;
    }
    
    if (y || y === 0)
    {
        var ys = "" + y;
        if (ys.isInt()) ys += "px";
        elem.style.top = ys;
    }
},

resizeElem: function(elem, w, h)
{
    if (w)
    {
        var ws = "" + w;
        if (ws.isInt()) ws += "px";
        try
        {
            elem.style.width = ws;
        }
        catch(ex1)
        {
        }
    }
    
    if (h)
    {
        var hs = "" + h;
        if (hs.isInt()) hs += "px";        
        try
        {
            elem.style.height = hs;
        }
        catch(ex2)
        {
        }
    }
},

getClient: function()
{
    var w = document.compatMode=='CSS1Compat' && !window.opera?document.documentElement.clientWidth:document.body.clientWidth;
    var h = document.compatMode=='CSS1Compat' && !window.opera?document.documentElement.clientHeight:document.body.clientHeight;
    
    return {w: w, h: h};
},

/*** Mouse ***/

getMouse: function(e)
{
    var xm = -1488;
    var ym = -1488;
    var okm = false;

    if (e)
    {
        xm = e.pageX;
        ym = e.pageY;
        okm = true;
    }
    else if (window.event)
    {
        xm = event.x;
        ym = event.y;
        okm = true;
    }
    
    return {ok: okm, x: xm, y: ym};
},

mouseInRect: function(e, rect)
{
    var m = DomTool.getMouse(e);
    return DomTool.inRect(m, rect);
},

mouseOver: function(e, elem)
{
    return DomTool.mouseInRect(e, DomTool.getRect(elem));
},

mouseOverId: function(e, id)
{
    return DomTool.mouseInRect(e, DomTool.getRect(DomTool.getElem(id)));
},

/*** DOM elements ***/

// DOM elements getters

testChild: function(chld, par)
{
    var testPar = chld.parentNode;
    while (1)    
    {
        if (!testPar) return false;
        if (testPar == par) return true;
        
        testPar = testPar.parentNode;
    }
},

getGrandParent: function(elem, depth)
{
    var curr = elem;
    
    for (var i = 0; i < depth; ++i)
    {
        curr = curr.parentNode;
    }
    
    return curr;
},

getElem: function(id)
{
    var elem = document.getElementById(id);
    return elem;
},

getTbody: function(tableId)
{
    return DomTool.getElem(tableId).tBodies[0];
},

docBody: null,
getBody: function()
{
    if (!DomTool.docBody)
    {
        DomTool.docBody = document.getElementsByTagName("body")[0];
    }
    
    return DomTool.docBody;
},

// DOM nodes makers

makeText: function(txt)
{
    var node = document.createTextNode(txt);
    return node;
},

addText: function(par, txt)
{
    return par.appendChild(DomTool.makeText(txt));
},

makeElem: function(tag, htm, css)
{
    var elem = document.createElement(tag);
    if (css) elem.className = css;
    if (htm || htm === 0) elem.innerHTML = htm;

    return elem;
},

makeDiv: function(htm, css)
{
    return DomTool.makeElem("div", htm, css);
},

makeSpan: function(htm, css)
{
    return DomTool.makeElem("span", htm, css);
},

makeImg: function(src, css)
{
    var img = DomTool.makeElem("img", null, css);
    img.src = src;
    return img;
},

// DOM elements adders

clearFloat: function(par)
{
    var clr = DomTool.addDiv(par);
    clr.style.clear = "both";
},

clearFloatSpan: function(par)
{
    var clr = DomTool.addSpan(par);
    clr.style.display = "block";
    clr.style.clear = "both";
},

addElem: function(par, tag, htm, css)
{
    var elem = DomTool.makeElem(tag, htm, css);
    if (par) par.appendChild(elem);
    
    return elem;
},

addDiv: function(par, htm, css)
{
    return DomTool.addElem(par, "div", htm, css);
},

addSpan: function(par, htm, css)
{
    return DomTool.addElem(par, "span", htm, css);
},

addTable: function(par, css, noTBody)
{
    var tab = DomTool.addElem(par, "table", null, css);
    if (!noTBody)
    {
        var tbody = DomTool.addTBody(tab);
        tab._tbody = tbody;
    }
    return tab;
},

addA: function(par, href, htm, css)
{
    var a = DomTool.addElem(par, "a", htm, css);
    if (href) a.href = href;
    return a;
},

addImg: function(par, src, css)
{
    var img = DomTool.addElem(par, "img", null, css);
    if (src) img.src = src;
    return img;
},

addInput: function(par, type, val, css)
{   
    var inp = DomTool.makeElem("input", null, css);
    inp.type = type;
    if (val) inp.value = val;
    if (par) par.appendChild(inp);
    
    return inp;
},

addButton: function(parent, val, css, onclick)
{
    var but = DomTool.addInput(parent, "button", val, css);    
    but.onclick = onclick ? onclick : null;
    return but;
},

addEdit: function(parent, val, css)
{
    return DomTool.addInput(parent, "text", val, css);
},

addCheck: function(par, checked, id, labelText, checkCss, labelCss)
{
    var ch = DomTool.addInput(par, "checkbox", null, checkCss);
    if (checked) ch.checked = "checked";
    if (id) ch.id = id;
    if (labelText) DomTool.addLabel(par, ch, labelText, labelCss);
    return ch;
},

addRadio: function(par, checked, id, name, labelText, radioCss, labelCss)
{
    var ra = DomTool.addInput(par, "radio", null, radioCss);
    if (checked) ra.checked = "checked";
    if (id) ra.id = id;
    if (name) ra.name = name;
    if (labelText) DomTool.addLabel(par, ra, labelText, labelCss);
    return ra;
},

addLabel: function(par, forElem, htm, css)
{
    var lbl = DomTool.addElem(par, "label", htm, css);
    if (forElem && forElem.id) lbl.htmlFor = forElem.id;
    return lbl;
},

addSelect: function(par, css)
{
    return DomTool.addElem(par, "select", null, css);
},

// adding to known parent
addElemWithCheck: function(par, parTag, tag, htm, css)
{
    if (par.tagName.toLowerCase() != parTag.toLowerCase()) return null;
    return DomTool.addElem(par, tag, htm, css);
},

addTBody: function(parentTable)
{
    return DomTool.addElemWithCheck(parentTable, "table", "tbody");
},

addTr: function(parentTbody, css)
{
    return DomTool.addElemWithCheck(parentTbody, "tbody", "tr", null, css);
},

addTd: function(parentTr, htm, css, ignoreEmpty)
{
    if (!htm && !(htm === 0) && !ignoreEmpty) htm = "&nbsp;";
    var td = DomTool.addElemWithCheck(parentTr, "tr", "td", htm, css);
    
    return td;
},

addOption: function(parentSelect, htm, css, ignoreEmpty)
{
    if (!htm && !(htm === 0) && !ignoreEmpty) htm = "&nbsp;";
    var opt = DomTool.addElemWithCheck(parentSelect, "select", "option", htm, css);
    
    return opt;
},

addOptionEx: function(parentSelect, htm, val, css, ignoreEmpty)
{
    if (!htm && !(htm === 0) && !ignoreEmpty) htm = "&nbsp;";
    var opt = DomTool.addElemWithCheck(parentSelect, "select", "option", htm, css);
    opt.value = val;
    opt.name = val;
    
    return opt;
},

/*** html ***/
makeImgHtm: function(img, style)
{
    if (!style) style = "";
    var htm = StringTool.format("<img src='{0}' style='{1}'/>", Global.getImgUrl(img), style);
    return htm;
}

};

