var ch_expander_intervals = [];

function ch_expander(id) {
    this.effect_speed = 3;
    this.slide_int = 10;
    this.target_height;
    this.exclusive = false;

    this._get_hidden_height = function(node) {
        var old_overflow = node.style.overflow;
        node.style.overflow = 'scroll';
        var height = node.scrollHeight;
        node.style.overflow = old_overflow;
        return height;
    }

    this.init_slide = function(id, dir) {
        var slider = document.getElementById(id);
        var origin_id = 'ch_expander_header_' + id.replace(/^.*([0-9])+/, '$1');

        if (ch_expander_intervals[id]) {
            clearInterval(ch_expander_intervals[id].int);
        }

        ch_expander_intervals[id] = [];
        ch_expander_intervals[id].id = [];

        if (dir == 'open') {
            if (document.getElementById(origin_id)) {
                document.getElementById(origin_id).className += ' active';
            }
        }
        else {
            if (document.getElementById(origin_id)) {
                document.getElementById(origin_id).className = document.getElementById(origin_id).className.replace(' active', '');
            }
        }

        var obj = this;
        var callback = function(id, dir) {
            obj.slide(id, dir);
        }
        ch_expander_intervals[id].int = setInterval(function() {callback(id, dir);}, this.slide_int);
    }

    this.slide = function(id, dir) {
        // An extra test here to cope with IE7.
        var slider = document.getElementById(id);
        if (!slider) {
            slider_height = 0;
        }
        else {
            var slider_height = parseInt(slider.style.height);
            if (isNaN(slider_height)) {
                slider_height = 0;
            }
        }

        if (dir == 'open') {
            if (slider_height >= this.target_height) {
                clearInterval(ch_expander_intervals[id].int);
                return;
            }
            var diff = (this.target_height - slider_height) / this.effect_speed;
            var min_diff = diff / 10;
            slider.style.height = slider_height + (diff < min_diff ? min_diff : diff) + 'px';
        } 
        else if (dir == 'close') {
            if (slider_height <= 0) {
                clearInterval(ch_expander_intervals[id].int);
                return;
            }
            slider.style.height = slider_height - (slider_height / this.effect_speed) + 'px';
        }
    }

    this.run = function(id) {
        var slider = document.getElementById(id);

        this.target_height = this._get_hidden_height(slider);

        if (this.exclusive) {
            for (var close_id in ch_expander_intervals) {
                this.init_slide(close_id, 'close');
           }
        }

        var dir = 'open';
        if (parseInt(slider.style.height) >= this.target_height - (this.target_height / 2)) {
            dir = 'close';
        }
        this.init_slide(id, dir);
    }
}
