function scroller(s_block, s_scroller) {
    this.s_block = s_block;
    this.o_block = $(s_block);

    this.o_frame = this.o_block.parentNode;

    if (parseInt(this.o_frame.offsetHeight) < parseInt(this.o_block.scrollHeight)) {
        $(s_scroller).show();
    }

    // prepare block
    this.o_block.style.top = '0px';

    this.i_minLimit = parseInt(this.o_frame.offsetHeight) - parseInt(this.o_block.scrollHeight) + 2;
    this.i_maxLimit = 0;
}

scroller.a_instances = new Object();

scroller.setup = function(s_block, s_scroller) {
    scroller.a_instances[s_block] = new scroller(s_block, s_scroller);
}

scroller.up = function(s_block, s_callback) {
    scroller.a_instances[s_block].up(s_callback);
}

scroller.down = function(s_block, s_callback) {
    scroller.a_instances[s_block].down(s_callback);
}

scroller.stop = function(s_block) {
    scroller.a_instances[s_block].stop();
}

scroller.scroll = function(s_block) {
    scroller.a_instances[s_block].scroll();
}

scroller.prototype.up = function(s_callback) {
    this.stop();
    var i_distance = Math.abs(parseInt(this.o_block.style.top));
    var i_duration = Math.abs(i_distance) / 150;
    this.o_effect = new Effect.Move(this.o_block, {x : 0, y : i_distance, duration: i_duration, transition: Effect.Transitions.linear, afterFinish: s_callback});
}

scroller.prototype.down = function(s_callback) {
    this.stop();
    var i_distance = this.i_minLimit - parseInt(this.o_block.style.top);
    var i_duration = Math.abs(i_distance) / 150;
    this.o_effect = new Effect.Move(this.o_block, {x : 0, y : i_distance, duration: i_duration, transition: Effect.Transitions.linear, afterFinish: s_callback});
}

scroller.prototype.stop = function(s_callback) {
    try {
        this.o_effect.cancel();
    }
    catch(o_event) {
    }
}
