/**
 *
 *
 * 
 * 
 * 
 * 
 * @copyright   Silicon Mechanics
 * @license     LGPL
 *
 * @package     SiMech
 * @subpackage  Javascript
 *
 * @uses        get_element()
 * @uses        add_event()
 *
/**/

// Some constants for various key codes
    var KEY_BS  = 8;
    var KEY_DEL = 46;

// Keep track of the requested resize field and event so the timer doesn't trip on itself
    var textarea_autorows_element = null;
    var textarea_autorows_length  = null;

// Enable the autorows handler function on all requested textarea fields
    add_event(window, 'load', parse_textarea_autorows);
    function parse_textarea_autorows(w) {
    // Make sure we got the right window
        if (typeof w == 'undefined' || typeof w.document == 'undefined')
            w = window;
        if (!w)
            return;
    // Only process textareas
        var text = w.document.getElementsByTagName('textarea');
        for (var i=0; i<text.length; i++) {
            text[i].autorows_max = text[i].getAttribute('autorows');
            if (text[i].autorows_max && text[i].autorows_max.length) {
                if (parseInt(text[i].autorows_max) < 1)
                    text[i].autorows_max = null;
            // First, run textarea_autorows on the field as it stands now
                textarea_autorows_timer(text[i], true);
            // Then, populate the event code
                add_event(text[i], 'keyup', function (e) {
                                                textarea_autorows_timer(this);
                                            });
            }
        }
    // Handle any subframes
        if (w.frames) {
            for(var i=0; i<w.frames.length; i++){
                parse_textarea_autorows(w.frames[i]);
            }
        }
    }

// Start the
    function textarea_autorows_timer(element, immediate) {
    // Nothing
        if (!element)
            return;
    // Same element still waiting, just leave
        if (textarea_autorows_element == element)
            return;
    // Last element hasn't resized yet -- do it immediately
        if (textarea_autorows_element != null)
            textarea_autorows();
    // Empty or only a single char?  Leave early
        if (element.value.length < 2) {
            element.autorows_cache = element.value;
            element.rows           = (element.value == "\n" ? 3 : 2);
            return;
        }
    // If the value hasn't changed, leave early
        if (element.autorows_cache == element.value)
            return;
    // Set the element and cache
        textarea_autorows_element = element;
        element.autorows_cache    = element.value;
    // Execute immediately
        if (immediate)
            textarea_autorows();
        else
            setTimeout(textarea_autorows, 500);
    }

// Adjust the number of rows in textarea id to match the number of lines it has
    function textarea_autorows() {
        var element = textarea_autorows_element;
        if (!element)
            return;
    // Reset the currently-active element so we can start the timer again
        textarea_autorows_element = null;
    // Create a shorter variable to hold the max rows to resize to
        var max = element.autorows_max;
    // Quick check to see if this is a huge piece of text and leave early
        if (max != null && element.rows == max) {
            if (element.value.split("\n", max).length >= max)
                return;
        }
    // Create an invisible clone of this node.
        var clone = element.cloneNode(false);
        clone.style.visibility = 'hidden';
        clone.style.position   = 'absolute';
        clone.value            = element.value;
        clone.rows             = 1;
        element.parentNode.appendChild(clone);
    // Need to make the textarea larger?
        if (clone.scrollHeight > clone.clientHeight) {
        // Get the current element height
            var h = clone.clientHeight;
        // Add a row
            clone.rows++;
        // Haven't maxed out yet
            if (clone.rows < max) {
            // Determine the height of each row
                var row_height = Math.abs(clone.clientHeight - h);
            // And how many rows the current data is taking up
                var rows = Math.ceil(clone.scrollHeight / row_height);
            // Deal with the horizontal scroll bar
                if (clone.scrollWidth > clone.clientWidth)
                    rows++;
            }
        // Increment the displayed rows as necessary
            element.rows = (max != null) ? Math.min(rows, max) : rows;
        }
    // clone.rows is already set as low as it can be, so no calc needed
        else {
            element.rows = 2;
        }
    // Remove the clone node
        element.parentNode.removeChild(clone);
    }

