// xpath.js required (for IE :))
// #NO_COMPILE

function TAutoSize(params, id)   
{
    if (!id)
        id = "AutoSize";
    this.THIS = this;
    this.id = id;
    this.params = params;
    this.dumpData = false;
    //this.dumpSpeed = true;
    
    // for new browsers - autosize using Flex Box Model
    this.flex = true;

    addObject(this);
    this._create();
}

extendClass(TAutoSize, TObject);

TAutoSize.prototype.create = function()
{
    this.domChangeTimer = 100; // 10
    
    var _this = this;
    extendFunction(addClassName, function(){
        parent(auto); 
        if(className.indexOf('auto') == 0 && getObject('AutoSize')) 
            getObject('AutoSize').onDOMChange();
    });
    extendFunction(removeClassName, function(){
        parent(auto); 
        if(className.indexOf('auto') == 0 && getObject('AutoSize')) 
            getObject('AutoSize').onDOMChange()
    });
    extendFunction(setStyle, function(){
        parent(auto); 
        if (typeof(value) == "string" && value.indexOf("100%") != -1 && getObject('AutoSize')) 
            getObject('AutoSize').onDOMChange()
    });
    extendFunction(setHtml, function(){
        parent(auto); 
        if (getObject('AutoSize'))
            getObject('AutoSize').onDOMChange()
    });
        
    addEvent(window, 'load', function(){_this.onDOMChange()});
}

TAutoSize.prototype.onDOMChange = function(e)
{
    if (this._onDOMChangeTimeout)
        clearTimeout(this._onDOMChangeTimeout);

    var _this = this;
    this._onDOMChangeTimeout = setTimeout(function(){_this._onDOMChange()}, this.domChangeTimer);
}
    
TAutoSize.prototype._onDOMChange = function(e)
{
    startProfiler("TAutoSize::_onDOMChange()");
    this.dumpTimeStart("_onDOMChange()");
    //dump("---");
    //dump(now());
    
    startProfiler("TAutoSize::_onDOMChange() - 1");
    var newFound = this.findNewElements();
    //dump(newFound.length);
    stopProfiler("TAutoSize::_onDOMChange() - 1");

    startProfiler("TAutoSize::_onDOMChange() - 2");
    if (newFound.length)
    {
        for (var i = 0 ; i < newFound.length ; i++)
            this.autoSizeElement(newFound[i]);
    }
    stopProfiler("TAutoSize::_onDOMChange() - 2");

    //dump(now());
    this.dumpTime("_onDOMChange");
    stopProfiler("TAutoSize::_onDOMChange()");
}

TAutoSize.prototype.isAutoSizeElement = function(elem)
{
    return(elem.AutoSize != null);
}

TAutoSize.prototype.forceResize = function()
{
    // deprecated
}

TAutoSize.prototype.getAutoSizeElements = function()
{
    function concat(x1, x2, x3, x4, x5, x6, x7, x8, x9)
    {
        var ret = [];
        if (x1)
            for (var i = 0 ; i < x1.length ; i++)
                ret.push(x1[i]);
        if (x2)
            for (var i = 0 ; i < x2.length ; i++)
                ret.push(x2[i]);
        if (x3)
            for (var i = 0 ; i < x3.length ; i++)
                ret.push(x3[i]);
        if (x4)
            for (var i = 0 ; i < x4.length ; i++)
                ret.push(x4[i]);
        if (x5)
            for (var i = 0 ; i < x5.length ; i++)
                ret.push(x5[i]);
        if (x6)
            for (var i = 0 ; i < x6.length ; i++)
                ret.push(x6[i]);
        if (x7)
            for (var i = 0 ; i < x7.length ; i++)
                ret.push(x7[i]);
        if (x8)
            for (var i = 0 ; i < x8.length ; i++)
                ret.push(x8[i]);
        if (x9)
            for (var i = 0 ; i < x9.length ; i++)
                ret.push(x9[i]);
        
        return(ret);
    }
    
    var elems1 = getElementsByClassName("autosize");
    var elems2 = getElementsByClassName("autowidth");
    var elems3 = getElementsByClassName("autoheight");
    var elems4 = getElementsByClassName("autofill");
    var elems5 = getElementsByClassName("autofillwidth");
    var elems6 = getElementsByClassName("autofillheight");

    var elems = concat(elems1, elems2, elems3, elems4, elems5, elems6);
    
    return(elems);
}

TAutoSize.prototype.findNewElements = function()
{
    this.dumpTimeStart("findNewElements()");

    var newFound = [];
    var elems = this.getAutoSizeElements();

    this.dumpTimeContinue('getElementsByTagName("*")');
    
    for (var i = 0 ; i < elems.length ; i++)
    {
        var elem = elems[i];

        if (!this.isAutoSizeElement(elem))
        {
            elem.AutoSize = this;

            newFound.push(elem);
        }
    }
    this.dump("TAutoSize::findElements(): new found "+newFound.length);
    
    this.dumpTime("findElements()");
    return(newFound);

}

TAutoSize.prototype.autoSizeElement = function(elem)
{
    if (!elem)
        throw("TAutoSize.autoSizeElement(): trying to autosize non existing element (maybe has been removed from DOM)");

    if (!elem.AutoSize)
    {
        _throw("TAutoSize.autoSizeElement(): trying to autosize non autosizable element - "+htmlentities(getTag(elem)));
        return(true);
    }
    
    this.dumpTimeStart("autoSizeElement()");

    var parentNode = elem._autoSizeParentNode || elem.parentNode;
    var sElems = getSiblingNodes(elem);
    var cssFloat = "";
    var cssDisplay = "";

    for (var i = 0 ; i < sElems.length ; i++)
    {
        if (sElems[i].tagName)
        {
            //dump("-");
            //dump(sElems[i]);
            if (getStyle(sElems[i], "float") != "none")
            {
                cssFloat = getStyle(sElems[i], "float");
                if (cssFloat == "right")
                {
                    setStyle(sElems[i], "order", "2");
                    //dump(1);
                }
            }
            if (getStyle(sElems[i], "display") != "block" && getStyle(sElems[i], "display") != "flex" && getStyle(sElems[i], "display") != "none")
                cssDisplay = getStyle(sElems[i], "display");
            if (hasClassName(sElems[i], "autoheight"))
                cssFloat = "left";
        }
    }
    
    //dump(cssFloat);
    
    if (!cssFloat && !cssDisplay)
        setStyle(parentNode, "flex-direction", "column");
    else
        setStyle(parentNode, "flex-direction", "row");
                    
    parentNode._hideOldDisplay = "flex";
    if (getStyle(parentNode, "display") == "none")
    {
    }
    else
        setStyle(parentNode, "display", "flex");
        
    //dump("*");
    //dump(elem);
    //dump(now());
    var width = getStyle(elem, "width");
    var height = getStyle(elem, "height");

    //dump(width);
    //dump(height);
    //dump(now());
    
    //return;
    
    if (width == "auto" || width == "100%")
    {
        width = "";
        setStyle(elem, "width", "auto");
    }
    if (height == "auto" || height == "100%")
    {
        height = "";
        setStyle(elem, "height", "auto");
    }
    
    //setStyle(elem, "flex", (width ? width : ((hasClassName(elem, "autoheight") || hasClassName(elem, "autofillheight")) && !hasClassName(elem, "autofill") ? "0" : "1"))+" "+(height ? height : ((hasClassName(elem, "autowidth") || hasClassName(elem, "autofillwidth")) && !hasClassName(elem, "autofill") ? "0" : "1"))+" auto");
    //setStyle(elem, "flex", ((width || hasClassName(elem, "autoheight") || hasClassName(elem, "autofillheight") || height || hasClassName(elem, "autowidth") || hasClassName(elem, "autofillwidth")) && !hasClassName(elem, "autofill") ? "0 0" : "1 1")+" auto");
    setStyle(elem, "flex", ((width || height) && !hasClassName(elem, "autofill") ? "0 0" : "1 1")+" auto");
            
    this.dumpTime("autoSizeElement()");

    return(true);
}



//addEvent(window, 'load', function(){window.AutoSize = new TAutoSize();});
window.AutoSize = new TAutoSize();