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

function TAutoSize(params, id)   
{
    if (!id)
        id = "AutoSize";
    this.THIS = this;
    this.id = id;
    this.params = params;
    
    // zrusit onTimer a udelat to tak, ze se to bude hledat pri setHTML a appendChild... atd...
    this.timer = 2000;
    this.domChangeTimer = 10;
    this.timerCounter = 0;
    this.keyDebug = false; // press [INSERT] to simulate timer, [DELETE] to one by one element resize
    this.resizeCounter = 0; // for debug
    
    this.elements = [];

    this.dumpData = false;
    this.dumpSpeed = true;
    this.dumpIndent = 0; // 10
    this.elementsToResize = [];
    
    addObject(this);
    this.create();
}

extendClass(TAutoSize, TObject);

TAutoSize.prototype.create = function()
{
    var _this = this;
    
    if (this.keyDebug)
    {
        this.dump("AutoSize: press [INSERT] to find new elements, press [DELETE] to autosize elements");
        addEvent(window, "keydown", function(e){_this._onKeyDown(e)});
    }
    else
    {
        //addEvent(document.body, "DOMSubtreeModified", function(e){_this.onDOMChange(e)});
        //setTimeout(function(){_this._onTimer()}, 500);

        var _this = this;
        
        extendFunction(addClassName, function(){parent(auto); if(className.indexOf('auto') == 0) getObject('AutoSize').onDOMChange()});
        extendFunction(removeClassName, function(){parent(auto); if(className.indexOf('auto') == 0) getObject('AutoSize').onDOMChange()});
        extendFunction(setStyle, function(){parent(auto); if (typeof(value) == "string" && value.indexOf("100%") != -1) getObject('AutoSize').onDOMChange()});
        extendFunction(setHtml, function(){parent(auto); getObject('AutoSize').onDOMChange()});
    }
    
    //alert(1);
    this._onDOMChange();
    
    
}

TAutoSize.prototype.onDOMChange = function(e)
{
    //return;
    //alert('onDOMChange');
    if (this._onDOMChangeTimeout)
        clearTimeout(this._onDOMChangeTimeout);

    var _this = this;
    this._onDOMChangeTimeout = setTimeout(function(){_this._onDOMChange()}, this.domChangeTimer);
}
    
TAutoSize.prototype._onDOMChange = function(e)
{
    this.dumpTimeStart("_onDOMChange()");
    if (!this.elementsToResize.length)
    {
        var newFound = this.findNewElements();
        //alert(newFound.length);
        if (newFound.length)
            this.autoSizeNewElements(newFound);
    
        this.timerCounter++;
        //if (this.timerCounter < 2)
    }
    else
    {
        this.dump("Nothing done, because there is "+this.elementsToResize.length+" elements remaining to resize");
        
        //this.onDOMChange(e);
    }
    //this.dumpTimeStart("_onDOMChange()");
    this.dumpTime("_onDOMChange");
}

TAutoSize.prototype.addElement = function(elem)
{
    for (var i = 0 ; i < this.elements ; i++)
    {
        if (this.elements[i] == elem)
            return;
    }
    
    this.elements.push(elem);
}

TAutoSize.prototype._onKeyDown = function(e)
{
    var e = getKeyEvent(e);
    
    //alert(e.keyCode);
    //alert(VK_INSERT);
    if (e.keyCode == VK_INSERT)
    {
        //this.XXX = true;
        
        //var callStack = getCallStack();
        //return;
        this._onTimer();
    }

    if (e.keyCode == VK_DELETE)
    {
        //this.XXX = true;
        
        //var callStack = getCallStack();
        //return;
        this._resizeElements();
    }
}

TAutoSize.prototype._resizeElements = function()
{
    this.dumpTimeStart("_resizeElements()");
    if (this.elementsToResize.length)
    {
        while(this.elementsToResize.length)
        {
            var elem = this.elementsToResize.shift();
            this.autoSizeElement(elem);
        }
        /*
        var elem = this.elementsToResize.shift();
        this.autoSizeElement(elem);
        
        var _this = this;
        if (!this.keyDebug)
            setTimeout(function(){_this._resizeElements()}, 10);
        */
    }
    this.dumpTime("_resizeElements()");
    this.dump("TAutoSize._resizeElements(): remaining: "+this.elementsToResize.length);
}

/*
TAutoSize.prototype._findElements = function(elements)
{
    var newFound = 0;
    for (var i = 0 ; i < elements.length ; i++)
    {
        var elem = elements[i];
        if (!elem.AutoSize)
        {
            this.elements.push(elem);
            elem.AutoSize = this;
            newFound++;
            //this.dump("TAutoSize::findElements(): added("+outerHTML(elem)+")");
        }
    }
    this.dump("TAutoSize::findElements(): new found "+newFound);
}
*/

TAutoSize.prototype.isAutoSizeElement = function(elem)
{
    return(elem.AutoSize);
    
    for (var i = 0 ; i < this.elements.length ; i++)
    {
        if (this.elements[i] == elem)
            return(true);
    }
    
    return(false);
}

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

    //return([]);
    
    var newFound = [];
    
    //var elems = getElementsByTagName("*");
    //var elems = getElementsByClassName("autosize");
    

    function concat(x1, x2, x3, x4)
    {
        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]);
        
        return(ret);
    }
    
    var elems1 = getElementsByClassName("autosize");
    var elems2 = getElementsByClassName("autowidth");
    var elems3 = getElementsByClassName("autoheight");
    var elems4 = getElementsByClassName("autofill");

    var elems = concat(elems1, elems2, elems3, elems4);
    this.dumpTimeContinue('getElementsByTagName("*")');
    
    //var elems = document.getElementsByClassName(["autosize", "autowidth", "autoheight"]);
    //var elems = document.getElementsByClassName("autosize");

    //this.dumpTimeStart();
    this.dump("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=", this.keyDebug);
    for (var i = 0 ; i < elems.length ; i++)
    {
        var elem = elems[i];
        //if ((elem.tagName == "DIV" || elem.tagName == "TEXTAREA" || elem.tagName == "VIDEO" || elem.tagName == "EMBED" || elem.tagName == "OBJECT") && (hasClassName(elem, "autosize") || hasClassName(elem, "autowidth") || hasClassName(elem, "autoheight") || hasClassName(elem, "autofill") || getStyle(elem, "width") == "100%" || getStyle(elem, "height") == "100%"))
        if (true)
        {
            if (!this.isAutoSizeElement(elem))
            {
                elem.AutoSize = this;
                elem.autoSizeParentList = [];
                elem.autoSizeChildList = [];
                
                var list = getParentNodes(elem);
                for (var l = 0 ; l < list.length ; l++)
                {
                    var _elem = list[l];
                    if (this.isAutoSizeElement(_elem))
                    {
                        elem.autoSizeParentList.push(_elem);
                        _elem.autoSizeChildList.push(elem);
                    }
                }
                
                var list = getChildNodes(elem, -1);
                for (var l = 0 ; l < list.length ; l++)
                {
                    var _elem = list[l];
                    if (this.isAutoSizeElement(_elem))
                    {
                        elem.autoSizeChildList.push(_elem);
                        _elem.autoSizeParentList.push(elem);
                    }
                }

                this.elements.push(elem);
                newFound.push(elem);

                
                // resize event
                //this.dump(typeof(elem.parentNode.autoSizeElements));
                if (typeof(elem.parentNode.autoSizeElements) != "object")
                    elem.parentNode.autoSizeElements = [];
                elem.parentNode.autoSizeElements.push(elem);

                var _this = this;
                addEvent(elem.parentNode, "resize", function(elem){_this._onParentNodeResize(elem)});
                this.dump("TAutoSize::findElements(): added("+outerHTML(elem)+")");
            }
        }
    }
    this.dump("TAutoSize::findElements(): new found "+newFound.length);
    //this.dumpTime("TAutoSize::findElements()");
    
    this.dumpTime("findElements()");
    return(newFound);
    //this._findElements(foundElems);


    //this.dump(foundElems.length);
    
    /*
    this.dump("xpath ==========");
    var elems = getNodesByXPath("//div[contains(concat(' ',normalize-space(@class),' '),' autosize ')]");  
    this.dump(elems.length);
    //for (var i = 0 ; i < elems.length ; i++)
    //    this.dump(outerHTML(elems[i]));
        

    var elems = getNodesByXPath("//div[contains(@style,'100%')]");  
    this.dump(elems.length);

    //var elems = getNodesByXPath("//*[contains(concat(' ',normalize-space(@class),' '),' autosize ') or contains(@css,'100%')]");  
    //this.dump(elems.length);
    */
    /*
    this.dump("sly ==========");
    var rows = Sly.search('div[class*="autosize"]');
    this.dump(rows.length);
    //for (var i = 0 ; i < elems.length ; i++)
    //    this.dump(outerHTML(elems[i]));
    
    var rows = Sly.search('div[css*="100%"]');
    this.dump(rows.length);
    */
    //span[contains(@class, 'active')]
    
    // TODO - do all by findElementsByTagName
    //this._findElements(document.getElementsByClassName("autosize"));
    //this._findElements(document.getElementsByClassName("autowidth"));
    //this._findElements(document.getElementsByClassName("autoheight"));
    
    /*
    var elements = [];
    //var elems = findElementsByTagName("div");
    var elems = getElementsByTagName("*");
    for (var i = 0 ; i < elems.length ; i++)
    {
        var elem = elems[i];
        //var style = getStyle(elem, "height");
        if (!elem.AutoSize && getStyle(elem, "width") == "100%" || getStyle(elem, "height") == "100%" || elem.className.indexOf("autosize") > -1 || elem.className.indexOf("autowidth") > -1 || elem.className.indexOf("autoheight") > -1)
        {
            elements.push(elem);
        }
    }
    //this._findElements(elements);
    */
}

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");
    
    this.dumpTimeStart("autoSizeElement()");

    this.useParentOverflow = false;
    this.useHideElement = true;
    this.useOutline = false;
    
    // has been parent element resized?
    this.dump(outerHTML(elem, true));
    this.dump(elem.parentWidth);
    this.dump(elem.parentNode.offsetWidth);
    if (elem.parentWidth != elem.parentNode.offsetWidth || elem.parentHeight != elem.parentNode.offsetHeight)
    {
        //this.dumpTimeStart();
        this.resizeCounter++;
            
        this.dump("[ "+this.resizeCounter+" ] ===========================", this.keyDebug);
        this.dump("TAutoSize.autoSizeElement()");

        if (this.keyDebug && this.useOutline)
        {
            if (this.keyDebugLastElem)
                this.keyDebugLastElem.style.outline = "";
            elem.style.outline = "2px dotted #00FF00";
            this.keyDebugLastElem = elem;
        }
        
        // we need to disable scroll on all parent elements (otherwise there will remail scrollbar width and height space)
        
        // setting overflow:hidden or display:none on any parent element, that contains EMBED causes Flash to reload - may be fixed by moving embeds to body temporarily
        //var hideParentList = [];
        if (this.useParentOverflow)
        {
            var node = elem.parentNode;
            while(node)
            {
                /*if (node.style && (node.style.overflow == "auto" || node.style.overflow == "scroll"))*/
                if (node != document && node.tagName == "DIV")
                {
                    //var val = node.style.overflow;
                    //node.style.overflow = "hidden";

                    //hideParentList.push({'width':node.style.width,'height':node.style.height,'visibility':node.style.visibility})
            
                    if (this.useHideElement)
                    {
                        if (Browser.name == "Firefox" || Browser.name == "Chrome")
                        {
                            hideElement(node); // needed due to Flash reload bug
                        }
                        else
                        {
                            node._autoSizeOldOverflow = node.style.overflow;
                            node.style.overflow = "hidden";
                        }
                    }
                    else
                    {
                        node._autoSizeOldOverflow = node.style.overflow;
                        node.style.overflow = "hidden";
                    }
                    
                    /*
                    var elems = node.getElementsByTagName("embed");
                    this.dump("EMBED found: "+elems.length);
                    for (var i = 0 ; i < elems.length ; i++)
                    {
                        var elem = elems[i];
                        embedObjects.push({'elem':elem, 'parent':elem.parentNode, 'nextSibling':elem.nextSibling});
                        //elem.style.visibility = 'hidden';
                        //document.documentElement.appendChild(elem);
                        //return;
                    }        
                    //node.style.width = "1px";
                    //node.style.height = "1px";
                    //dump("A "+val);
                    */
                }
                
                node = node.parentNode;
            }
        }
        //this.dumpTimeContinue("parent");
        
        this.dump(elem);
        if (elem.parentNode != document)
            this.dump(elem.parentNode);
        if (elem.parentNode != document && elem.parentNode.parentNode != document)
            this.dump(elem.parentNode.parentNode);
        //this.dumpTimeContinue("dump");
        
        //var _display = elem.style.display;
        //if (elem.tagName != "OBJECT" && elem.tagName != "EMBED") // hiding causes Flash to reload
        //    elem.style.display = 'none';
        //else
        //{
        //    elem.style.width = '1px';
        //    elem.style.height = '1px';
        //}
        
        // never hide using display:none - it reloads Flash if any EMBED or OBJECT inside
        var _overflow = elem.style.overflow;
        //elem.style.overflow = 'hidden';
        
        var styleWidth = getStyle(elem, "width");
        var styleHeight = getStyle(elem, "height");
        if (styleWidth == "100%")
            addClassName(elem, "autowidth");
        if (styleHeight == "100%")
            addClassName(elem, "autoheight");
        
        var _width = elem.style.width;
        var _height = elem.style.height;
        
        elem.style.width = '1px';
        elem.style.height = '1px';

        // TODO UNCOMMENT
        //elem.style.overflow = 'hidden';
        
        //this.dumpTimeContinue("hide");

        var width = elem.parentNode.offsetWidth;
        //this.dumpTimeContinue("getting parent offset width");
        var height = elem.parentNode.offsetHeight;
        //this.dumpTimeContinue("getting parent offset height");

        //this.dumpTimeContinue("getting parent offset size - ("+_dump(outerHTML(elem, true))+")");
        //this.dumpTimeContinue("getting parent offset size");

        this.dump("parent.width="+width);
        this.dump("parent.height="+height);
        this.dump("parentWidth="+elem.parentWidth);
        this.dump("parentHeight="+elem.parentHeight);
        this.dump("parentWidthS="+elem.parentNode.style.width);
        this.dump("parentHeightS="+elem.parentNode.style.height);

        elem.parentWidth = width;
        elem.parentHeight = height;
        
        // THIS IS SLOW - because getStyle walks through all .style and loaded .css
        // BUT we need to decrement if using padding, border, ....
        /*
        width -= extractInt(getStyle(elem, "padding-left"), 0);
        width -= extractInt(getStyle(elem, "padding-right"), 0);
        width -= extractInt(getStyle(elem, "border-left-width"), 0);
        width -= extractInt(getStyle(elem, "border-right-width"), 0);
        height -= extractInt(getStyle(elem, "padding-top"), 0);
        height -= extractInt(getStyle(elem, "padding-bottom"), 0);
        height -= extractInt(getStyle(elem, "border-top-width"), 0);
        height -= extractInt(getStyle(elem, "border-bottom-width"), 0);

        width -= extractInt(getStyle(elem.parentNode, "padding-left"), 0);
        width -= extractInt(getStyle(elem.parentNode, "padding-right"), 0);
        //width -= extractInt(getStyle(elem.parentNode, "border-left-width"), 0);
        //width -= extractInt(getStyle(elem.parentNode, "border-right-width"), 0);
        height -= extractInt(getStyle(elem.parentNode, "padding-top"), 0);
        height -= extractInt(getStyle(elem.parentNode, "padding-bottom"), 0);
        //height -= extractInt(getStyle(elem.parentNode, "border-top-width"), 0);
        //height -= extractInt(getStyle(elem.parentNode, "border-bottom-width"), 0);

        //width += extractInt(elem.parentNode.scrollLeft, 0);
        //width -= extractInt(elem.scrollLeft, 0);
        */
       
        //var widthD = 0;
        //var heightD = 0;
        
        width = getRelativeWidth(elem, width);
        height = getRelativeHeight(elem, height);
        
        /*
        var formElemDefaultBorderWidth = 2;       // TEXTAREA without any border set has default border
        var style = getStyle(elem);
        
        widthD += extractInt(style.paddingLeft, 0);
        widthD += extractInt(style.paddingRight, 0);
        widthD += (typeof(style.borderLeftWidth) != "undefined" ? extractInt(style.borderLeftWidth, 0) : (elem.tagName == "TEXTAREA" ? formElemDefaultBorderWidth : 0));
        widthD += (typeof(style.borderRightWidth) != "undefined" ? extractInt(style.borderRightWidth, 0) : (elem.tagName == "TEXTAREA" ? formElemDefaultBorderWidth : 0));
        heightD += extractInt(style.paddingTop, 0);
        heightD += extractInt(style.paddingBottom, 0);
        heightD += (typeof(style.borderTopWidth) != "undefined" ? extractInt(style.borderTopWidth, 0) : (elem.tagName == "TEXTAREA" ? formElemDefaultBorderWidth : 0));
        heightD += (typeof(style.borderBottomWidth) != "undefined" ? extractInt(style.borderBottomWidth, 0) : (elem.tagName == "TEXTAREA" ? formElemDefaultBorderWidth : 0));
        widthD += extractInt(style.marginLeft, 0);
        widthD += extractInt(style.marginRight, 0);
        heightD += extractInt(style.marginTop, 0);
        heightD += extractInt(style.marginBottom, 0);
        */
        
        //dump(style);
        //dump(style.border);
        
        /*        
        var styleP = getStyle(elem.parentNode);
        widthD += extractInt(styleP.paddingLeft, 0);
        widthD += extractInt(styleP.paddingRight, 0);
        widthD += 2*extractInt(styleP.borderLeftWidth, 0);    // nechapu proc 2x ale funguje to, pokud ma parent border a jsme autofill
        widthD += 2*extractInt(styleP.borderRightWidth, 0);
        heightD += extractInt(styleP.paddingTop, 0);
        heightD += extractInt(styleP.paddingBottom, 0);
        heightD += 2*extractInt(styleP.borderTopWidth, 0);
        heightD += 2*extractInt(styleP.borderBottomWidth, 0);
        */
        
        var widthDP = 0;
        var heightDP = 0;

        var styleP = getStyle(elem.parentNode);
        widthDP += extractInt(styleP.paddingLeft, 0);
        widthDP += extractInt(styleP.paddingRight, 0);
        widthDP += extractInt(styleP.borderLeftWidth, 0);
        widthDP += extractInt(styleP.borderRightWidth, 0);
        heightDP += extractInt(styleP.paddingTop, 0);
        heightDP += extractInt(styleP.paddingBottom, 0);
        heightDP += extractInt(styleP.borderTopWidth, 0);
        heightDP += extractInt(styleP.borderBottomWidth, 0);

        //widthDP *= 2;
        //heightDP *= 2;
                
        //dump(extractInt(style.paddingLeft, 0));
        //dump(extractInt(style.borderLeftWidth, 0));
        
        this.dump("countedWidth="+width);
        this.dump("countedHeight="+height);
        
        //this.dump("widthDecrement="+widthD);
        //this.dump("heightDecrement="+heightD);

        this.dump("widthParentDecrement="+widthDP);
        this.dump("heightParentDecrement="+heightDP);

        //width -= widthD;
        //height -= heightD;

        width -= widthDP;
        height -= heightDP;


        //this.dump(height+" - "+elem.id+"/"+elem.className);
        //this.dumpTimeContinue("count size");
        
        if (hasClassName(elem, "autofill"))
        {
            if (elem.parentNode != document.body)
            {
                var siblings = getSiblingNodes(elem);
                for (var s = 0 ; s < siblings.length ; s++)
                {
                    var elemS = siblings[s];
                    var styleS = getStyle(elemS);
                    
                    var style = getStyle(elem);
                    if (!hasClassName(elemS, "debugAutoSizeCounter") && styleS.position != "absolute" && styleS.position != "relative")
                    {
                        widthD = 0;
                        heightD = 0;
                        //this.dump(elemS);
                        
                        
                        //width -= extractInt(style.marginLeft, 0);
                        //width -= extractInt(style.marginRight, 0);
                        if (styleS.float == "left" || styleS.float == "right" || style.float == "left" || style.float == "right")
                        {
                            widthD += extractInt(elemS.offsetWidth, 0);
                            widthD += extractInt(style.marginLeft, 0);
                            widthD += extractInt(style.marginRight, 0);
                        }
                        else
                        {
                            heightD += extractInt(elemS.offsetHeight, 0);
                            heightD += extractInt(style.marginTop, 0);
                            heightD += extractInt(style.marginBottom, 0);
                        }

                        this.dump("autofill sibling widthDecrement="+widthD);
                        this.dump("autofill sibling heightDecrement="+heightD);

                        
                        width -= widthD;
                        height -= heightD;
                        

                        //height -= extractInt(style.borderTopWidth, 0);
                        //height -= extractInt(style.borderBottomWidth, 0);
                        //dump(extractInt(style.paddingLeft, 0));
                        //dump(extractInt(style.borderLeftWidth, 0));
        
                        //dump(outerHTML(elemS, true));
                        //dump(elemS.style.borderLeftWidth);
                        //dump(getStyle(elemS, "border"));
                        //dump(getStyle(elemS, "border-left-width"));
                        //width -= extractInt(elemS.style.borderLeftWidth, 0);
                        //height -= extractInt(elemS.style.borderRightWidth, 0);
                    }
                }
            }
            //width -= 10; // border? 
            //height -= 10; // border? 
            //elem.style.outline = "1px dashed #00FF00";
        }
        //height -= 10;
        //this.dumpTimeContinue("autofill");
        
        
        width -= this.dumpIndent;
        height -= this.dumpIndent;

        width = Math.max(width, 0);
        height = Math.max(height, 0);
        
        //dump('styleWidth='+styleWidth);
        //dump('styleHeight='+styleHeight);
        if (hasClassName(elem, "autosize") || hasClassName(elem, "autowidth") || hasClassName(elem, "autofill"))
        {
            setStyle(elem, "width", width+'px');
            this.dump("newWidth: "+width);
        }
        else
            elem.style.width = _width;
        
        if (hasClassName(elem, "autosize") || hasClassName(elem, "autoheight") || hasClassName(elem, "autofill"))
        {
            setStyle(elem, "height", height+'px');
            this.dump("newHeight: "+height);
        }
        else
            elem.style.height = _height;
        //elem.style.width = width+'px';
        //elem.style.height = height+'px';
        
        //if (elem.tagName != "OBJECT" && elem.tagName != "EMBED") // hiding causes Flash to reload
        //    elem.style.display = _display;
        //elem.style.overflow = _overflow;
        
        //elem.style.overflow = _overflow;
        

        //this.dump(height+" - "+elem.id+"/"+elem.className);
        //this.dump(parentNode.tagName);
        //this.dump(parentNode.style.height);
        
        //this.dump("after autosize:");
        //this.dump(outerHTML(elem));

        //this.dumpTimeContinue("set width");

        // set back old overflow
        if (this.useParentOverflow)
        {
            var node = elem.parentNode;
            while(node)
            {
                /*if (node.style && (node.style.overflow == "auto" || node.style.overflow == "scroll"))*/
                if (node != document && node.tagName == "DIV")
                {
                    //var val = overflowParentList.shift();
                    //node.style.overflow = val;
                    
                    if (this.useHideElement)
                    {
                        if (Browser.name == "Firefox" || Browser.name == "Chrome")
                        {
                            showElement(node); // needed due to Flash reload bug
                        }
                        else
                        {
                            node.style.overflow = node._autoSizeOldOverflow;
                        }
                    }
                    else
                        node.style.overflow = node._autoSizeOldOverflow;
                    
                }
                
                node = node.parentNode;
            }
        }
        /*
        var node = elem.parentNode;
        while(node)
        {
            if (node._overflow)
            {
                node.style.overflow = node._overflow;
                //alert(node._overflow);
            }

            node = node.parentNode;
        }
        */
        
        //this.dumpTimeContinue("back overflow");

        if (false && this.dumpData)
        {
            var node1;
            if (elem.childNodes[0] && elem.childNodes[0].className == "debugAutoSizeCounter")
            {
                node1 = elem.childNodes[0];
            }
            else
            {
                node1 = createElement("div");
                node1.className = "debugAutoSizeCounter";
                node1.style.position = "absolute";
                setStyle(node1, "width", width+"px");
                node1.style.textAlign = "right";
                appendFirst(elem, node1);
            }

            var node2 = createElement("span");
            node2.style.background = "#0000FF";
            node2.style.color = "#FFFFFF";
            node2.style.fontWeight = "bold";
            node2.style.padding = "2px";
            node2.style.marginLeft = "4px";
            node2.innerHTML = this.resizeCounter;

            appendFirst(node1, node2);
            elem.style.outline = '2px dashed #0000FF';
        }
        //this.dumpTimeContinue("adding counter");
        
        //this.dumpTime();
    }

    this.dumpTime("autoSizeElement()");
}

TAutoSize.prototype.autoSizeNewElements = function(elems)
{
    ///Start();
    for (var i = 0 ; i < elems.length ; i++)
    {
        
        var elem = elems[i];
        this.elementsToResize.push(elem);

    }
    //this.dumpTime("autosize new elements (found: "+elems.length+")");
    if (!this.keyDebug)
        this._resizeElements();
}

TAutoSize.prototype.autoSizeRootElements = function()
{
    dump("TAutoSize.autoSizeRootElements is DEPRECATED");
    /*
    var rootElements = [];
    for (var i = 0 ; i < this.elements.length ; i++)
    {
        var elem = this.elements[i];
        elem.autoSized = false;
        
        if (!elem.autoSizeParentList.length)
            rootElements.push(elem);
    }

    for (var i = 0 ; i < rootElements.length ; i++)
    {
        this.dumpTimeStart();
        
        var elem = this.elements[i];
        //this.dump(" ========= AUTOSIZING ========== ");
        //this.dump(elem);
        //this.dump("autoSizeChildList: "+elem.autoSizeChildList.length);

        //this.dump(outerHTML(elem));
        // first we need to hide all child elements
        for (var c = 0 ; c < elem.autoSizeChildList.length ; c++)
        {
            var cElem = elem.autoSizeChildList[c];
            cElem.autoSizeOldDisplay = cElem.style.display;
            cElem.style.display = "none";
        }
        
        // now autosize element
        this.autoSizeElement(elem);
        
        // and autosize all children
        for (var c = 0 ; c < elem.autoSizeChildList.length ; c++)
        {
            var cElem = elem.autoSizeChildList[c];
            cElem.style.display = cElem.autoSizeOldDisplay;
            this.autoSizeElement(cElem);
        }

        //elem.autoSizing = true;
        //this.dump(elem.parentWidth+" != "+elem.parentNode.offsetWidth+" || "+elem.parentHeight+" != "+elem.parentNode.offsetHeight);
        //this.autoSizeElement(elem);
        this.dumpTime();
    }
    */
    
    
    
/*
    for (var i = 0 ; i < this.elements.length ; i++)
    {
        var elem = this.elements[i];

        if (elem.parentWidth != elem.parentNode.offsetWidth || elem.parentHeight != elem.parentNode.offsetHeight)
        {
            elem.autoSizing = true;
            this.dump(elem.parentWidth+" != "+elem.parentNode.offsetWidth+" || "+elem.parentHeight+" != "+elem.parentNode.offsetHeight);
            this.autoSizeElement(elem);
        }
        
        autoSizingElements.push(elem);
    }
*/

    /*
    
    var autoSizingElements = [];
    for (var i = 0 ; i < this.elements.length ; i++)
    {
        var elem = this.elements[i];

        if (elem.parentWidth != elem.parentNode.offsetWidth || elem.parentHeight != elem.parentNode.offsetHeight)
        {
            elem.autoSizing = true;
            this.dump(elem.parentWidth+" != "+elem.parentNode.offsetWidth+" || "+elem.parentHeight+" != "+elem.parentNode.offsetHeight);
            this.autoSizeElement(elem);
        }
        
        autoSizingElements.push(elem);
    }
    
    while(autoSizingElements.length)
    {
        for (var i = 0 ; i < autoSizingElements.length ; i++)
        {
            var elem = autoSizingElements[i];
            var hasParentToAutoSize = false;
            var _elem = elem.parentNode;
            while(_elem && _elem != document)
            {
                if (_elem.autoSizing)
                {
                    hasParentToAutoSize = true;
                    break;
                }
                _elem = _elem.parentNode;
            }
            
            if (!hasParentToAutoSize)
            {
                //this.dump(outerHTML(elem));
                if (elem.parentWidth != elem.parentNode.offsetWidth || elem.parentHeight != elem.parentNode.offsetHeight)
                {
                    this.dump(elem.parentWidth+" != "+elem.parentNode.offsetWidth+" || "+elem.parentHeight+" != "+elem.parentNode.offsetHeight);
                    this.autoSizeElement(elem);
                }
                elem.autoSizing = false;
                autoSizingElements.splice(i, 1);
            }
        }
    }
    */
}

TAutoSize.prototype._onTimer = function()
{
    //this.dump("TAutoSize._onTimer() - "+(new Date().toString()));
    //this.dumpTimeStart();
    
    if (!this.elementsToResize.length)
    {
        var newFound = this.findNewElements();
        if (newFound.length)
            this.autoSizeNewElements(newFound);
    
        this.timerCounter++;
        //if (this.timerCounter < 2)
    }
    else
        this.dump("Nothing done, because there is "+this.elementsToResize.length+" elements remaining to resize");
    
    var _this = this;
    if (!this.keyDebug)
        setTimeout(function(){_this._onTimer()}, this.timer);
    //this.dumpTime("TOTAL TIMER TIME");
}

TAutoSize.prototype._onParentNodeResize = function(elem)
{
    this.dump("TAutoSize._onParentNodeResize() - "+(new Date().toString()));
    //this.dumpTimeStart();
    
    for (var i = 0 ; i < elem.autoSizeElements.length ; i++)
    {
        this.elementsToResize.push(elem.autoSizeElements[i]);
    }
    
    //this.dumpTime("TOTAL ONRESIZE TIME");
    if (!this.keyDebug)
        this._resizeElements();
}

/*
var auto100HeightObjects = [];
var auto100HeightCounter = 0;
function auto100Height()
{
    if (document.all) // TODO for IE
        return;
    
    //addEvent(document.body, "change", function(){this.dump("onChange")});
    //this.dump(document.body, true, 0);
    return;
    this.dump(auto100HeightCounter, true);
    // find new elems
    var elems = findElementsByTagName("div");
    for (var i = 0 ; i < elems.length ; i++)
    {
        var elem = elems[i];
        //this.dump(elem.className);
        var style = getStyle(elem, "height");
        //this.dump(elem.className+' '+style);
        if (style == "100%" && !elem.auto100Height)
        {
            elem.auto100Height = true;
            auto100HeightObjects.push(elem);
            //this.dump('x');
        }
    }
    //return;
    //this.dump(auto100HeightObjects.length, true);
    
    for (var i = 0 ; i < auto100HeightObjects.length ; i++)
    {
        var elem = auto100HeightObjects[i];
        //elem.style.border = '2px dashed #0000FF';
        
        elem.style.height = '1px';

        var height = elem.parentNode.offsetHeight;
        //this.dump(elem.style.paddingTop);
        //this.dump(extractInt(elem.style.paddingTop));
        height -= extractInt(getStyle(elem, "padding-top"));
        height -= extractInt(getStyle(elem, "padding-bottom"));

        //this.dump(height+" - "+elem.id+"/"+elem.className);
        if (elem.parentNode != document.body)
        {
            var siblings = getSiblingNodes(elem);
            //this.dump(siblings.length);
            for (var s = 0 ; s < siblings.length ; s++)
            {
                var elemS = siblings[s];
                //this.dump(elemS.offsetHeight);
                height -= elemS.offsetHeight;
            }
        }
        
        elem.style.height = height+'px';

        //elem.style.background = '#EEEEFF';
        //this.dump(height+" - "+elem.id+"/"+elem.className);
        //this.dump(parentNode.tagName);
        //this.dump(parentNode.style.height);
    }
    //this.dump(auto100HeightObjects.length);
    
    auto100HeightCounter++;
    setTimeout("auto100Height()", 1000);
};

setTimeout("auto100Height()", 1000);
*/
