Element.addMethods(
{
    fixPNG: function(img, width, height)
    {
        if ((img.tagName == 'IMG') && (Fly.BrowserDetect.fixPNG))
        {
            var imgName = img.src.toUpperCase()

            if (imgName.substring(imgName.length - 3, imgName.length) == "PNG")
            {
                var html = new Array();

                html.push('<span');

                if (img.id)
                {
                    html.push(' id="');
                    html.push(img.id);
                    html.push('"');
                }
                if (img.className)
                {
                    html.push(' class="');
                    html.push(img.className);
                    html.push('"');
                }
                if (img.title)
                {
                    html.push(' title="');
                    html.push(img.title);
                    html.push('"');
                }
                else if (img.alt)
                {
                    html.push(' title="');
                    html.push(img.alt);
                    html.push('"');
                }
                html.push(' style="');

                if (img.align == "left")
                {
                    html.push("float:left;");
                }
                else if (img.align == "right")
                {
                    html.push("float:right;");
                }
                else
                {
                    html.push("position:relative;");
                }

                html.push("width:");
                html.push(width || img.width || parseInt(img.style.width));
                html.push("px;");

                html.push("height:");
                html.push(height || img.height || parseInt(img.style.height));
                html.push("px;");
                /*
                 var imgStyle =
                 img.style.cssText + ";" +
                 "overflow:auto;" +
                 ;
                 */

                if (img.parentElement && img.parentElement.style.cursor)
                {
                    html.push("cursor:");
                    html.push(img.parentElement.style.cursor);
                    html.push(";");
                }

                html.push("display:inline-block;");
                html.push("filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='");
                html.push(img.src);
                html.push("');");

                html.push('"></span>');

                if (JSLog.debugEnabled())
                {
                    JSLog.debug(html.join(''));
                }

                img.outerHTML = html.join('');
            }
        }
    },

    getForm: function(element)
    {
        return element.ancestors().find(function(e)
        {
            return e.tagName == 'FORM';
        });
    },

    setSelectedValue: function(element, value)
    {
        if (!element.options)
        {
            return;
        }

        if (element.options.length === 0)
        {
            return;
        }

        for (var i = 0; i < element.options.length; i = i + 1)
        {
            if (element.options[i].value == value)
            {
                element.selectedIndex = i;

                return;
            }
        }

        if (i == element.options.length)
        {
            element.selectedIndex = 0;
        }
    },

    isValid: function(element)
    {
        if (isNun(element.valid))
        {
            element.validate();
        }

        return (element.valid == true);
    },

    setValidator: function(element, marker, message, validator)
    {
        element.marker = marker;
        element.message = message;
        element.validator = validator;

        if (validator)
        {
            var listener = element.validate.bindAsEventListener(element);

            Event.observe(element, "change", listener);
            Event.observe(element, "keyup", listener);
        }
    },

    validate: function(element, event)
    {
        if (!element.validator)
        {
            element.valid = true;

            return;
        }

        var result = element.validator.call(null, element, event);

        if (element.marker)
        {
            var markerClass = result.markerClass;

            if (markerClass && markerClass != element.marker.className)
            {
                element.marker.className = markerClass;
            }

            var markerTitle = result.markerTitle || '';

            if (markerTitle != element.marker.title)
            {
                element.marker.title = markerTitle;
            }
        }

        if (element.message)
        {
            var messageText = result.messageText || '';

            if (messageText != element.message.innerHTML)
            {
                element.message.innerHTML = messageText;
            }
        }

        if (result.valid != element.valid)
        {
            element.valid = result.valid;

            if (!element.valid)
            {
                JSLog.log('validation', element.name + ":" + element.id + " is invalid.");
            }

            element.fire("fly:validation", {valid:result.valid});
        }

        return element.valid;
    },

    trimToFit: function(element)
    {
        element.trimInfo =
        {
            innerHTML: element.innerHTML,
            clientDimensions: element.clientDimensions()
        };

        element.doTrimToFit()

        new PeriodicalExecuter(element.retrimToFit.bind(element), 0.1);
    },

    retrimToFit: function(element)
    {
        var clientDimensions = element.clientDimensions();

        if ((element.trimInfo.clientDimensions.width != clientDimensions.width) ||
            (element.trimInfo.clientDimensions.height != clientDimensions.height))
        {
            element.trimInfo.clientDimensions.width = clientDimensions.width;
            element.trimInfo.clientDimensions.height = clientDimensions.height;

            element.innerHTML = element.trimInfo.innerHTML;

            element.doTrimToFit();
        }
    },

    doTrimToFit: function(element)
    {
        element = $(element);

        // if (element.offsetHeight <= element.clientHeight) return;

        var descendants = element.descendants();

        var bottom = element.offsetPosition().top +
                     element.clientDimensions().height -
                     parseInt(element.getStyle("paddingBottom"));
        parseInt(element.getStyle("borderTopWidth")) -
        parseInt(element.getStyle("paddingTop"));

        var i;

        for (i = descendants.length - 1; i >= 0; --i)
        {
            var descendant = descendants[i];

            var position = descendant.offsetPosition()

            var count = 0;

            if (position.top < bottom)
            {
                if (position.top + descendant.offsetHeight > bottom)
                {
                    if (descendant.innerHTML)
                    {
                        var html = descendant.innerHTML;

                        var minLength = 0;

                        var maxLength = html.length;

                        var fitLength = 0;

                        while (maxLength - minLength > 1)
                        {
                            var length = (maxLength + minLength) >> 1;

                            descendant.innerHTML = html.substring(0, length) + '...';

                            if (position.top + descendant.offsetHeight > bottom)
                            {
                                maxLength = length;
                            }
                            else
                            {
                                minLength = length;
                                fitLength = length;
                            }
                        }

                        var fitHTML = html.substring(0, fitLength).replace(/(\s*\.*)+$/g, '') + '...';

                        descendant.innerHTML = fitHTML;
                    }
                    else
                    {
                        descendant.parentNode.removeChild(descendant);
                    }
                }
            }
            else
            {
                descendant.parentNode.removeChild(descendant);
            }
        }
    },

    /*
     addEventListener: function(element, event, handler)
     {
     var chained = element[event];

     var listener = isNun(chained) ? handler : function()
     {
     chained.call(element, event);
     handler.call(element, event)
     };

     element[event] = listener.bindAsEventListener(element);
     },
     */

    setToolTip: function(element, toolTip)
    {
        element.toolTip = document.createElement('div');
        element.toolTip.className = 'toolTip';
        element.toolTip.style.position = 'absolute';
        element.toolTip.appendChild(toolTip);
        //element.addEventListener('onmouseover',
        element.onmouseover = function()
        {
            var position = element.offsetPosition();

            document.body.appendChild(element.toolTip);
            //element.toolTip.innerHTML = 'position:'+position.left+',ewidth:'
            //+element.offsetWidth+',twidth:'+element.toolTip.offsetWidth;

            element.toolTip.style.left =
            (position.left - (element.toolTip.offsetWidth - element.offsetWidth) / 2) + 'px';

            element.toolTip.style.top = (position.top + element.offsetHeight + 2) + 'px';
        };
        //);

        //element.addEventListener('onmouseout', function()
        element.onmouseout = function()
        {
            if (element.toolTip && element.toolTip.parentNode)
            {
                element.toolTip.parentNode.removeChild(element.toolTip);
            }
        };
        //);
    },

    offsetPosition: function(element)
    {
        var left = element.offsetLeft;
        var top = element.offsetTop;

        while (element = element.offsetParent)
        {
            left += element.offsetLeft;
            top += element.offsetTop;
        }

        return {
            left: left,
            top: top
        };
    },

    clientDimensions: function(element)
    {
        return {
            width: element.clientWidth,
            height: element.clientHeight
        };
    }
}
        );

