/**
 * Picture cascade niceness.
 */

var CASCADE_LEFT    = -1;
var CASCADE_RIGHT   = 1;

function Cascade(div_id, source, maximum) {

    this.viewport   = document.getElementById(div_id);
    this.scroller   = document.createElement("DIV");
    this.canvas     = document.createElement("DIV");

    this.direction  = CASCADE_RIGHT;
    this.max        = maximum;
    this.captions   = false;
    this.running    = false;
    this.current    = 0;
    this.pictures   = new Array();
    this.source     = source;

    // setup viewport
    this.viewport.style.padding = "0";
    this.scroller.style.overflow= "hidden";
    this.viewport.style.overflow= "hidden";
    if (!this.viewport.style.width) {
        var width   = this.viewport.clientWidth;
        this.viewport.style.width   = ""+width+"px";
        this.scroller.style.width   = ""+width+"px";
        this.resizable = true;
        this.window_width = document.body.clientWidth;
        YAHOO.util.Event.on(window, 'resize', function() { 
                var new_width = document.body.clientWidth;
                var diff = (new_width - this.window_width);
                var width = this.viewport.clientWidth + diff;
                if (this.next) {
                    var left  = this.next.offsetLeft - 20 + diff;
                    this.next.style.marginLeft = ""+left+"px";
                }
                this.viewport.style.width   = ""+width+"px";
                this.scroller.style.width   = ""+width+"px";
                this.window_width = document.body.clientWidth;
            }, null, this);

    }
    this.scroller.appendChild(this.canvas);
    this.viewport.appendChild(this.scroller);
    this.canvas.style.width = "0px";

}

Cascade.prototype.fetch_one  = function(success_callback) { 
    fail        = this.show_error;
    var trans = YAHOO.util.Connect.asyncRequest('GET', this.source, { success: success_callback, failure: fail, scope: this } ); 
};

Cascade.prototype.place      = function(obj) {
    obj.left = this.canvas.clientWidth;

    picture = document.createElement("IMG");
    picture.style.styleFloat = picture.style.cssFloat     = "left";
    picture.style.margin    = "0";
    picture.style.padding   = "0";
    
    picture.src = obj.url;
    width       = obj.width;
    if (this.fit) {
        width = this.fit(picture, obj);
    }
    new_width = this.canvas.clientWidth + width;
    obj.right = obj.left + width;
    this.canvas.style.width = "" + new_width + "px";
    this.canvas.appendChild(picture);

    this.pictures.push(obj);
};

Cascade.prototype.show_captions = function() {
    this.captions   = document.createElement("DIV");
    YAHOO.util.Dom.insertBefore(this.captions, this.scroller);
};

Cascade.prototype.init_captions = function() {
    this.captions.className         = "captions";
    this.captions.style.position    = "absolute";
    this.captions.style.overflow    = "hidden";
    this.captions.style.width       = this.viewport.style.width;
    this.captions_height            = this.captions.clientHeight;
    if (this.captions_height == 0) {
        this.captions_height = 50;
    }

    if (this.captions.parentNode == this.captions.offsetParent) {
        this.captions.style.top         = ""+(this.viewport.clientHeight- this.captions_height)+"px";
    } else {
        this.captions.style.top         = ""+(this.viewport.clientTop + this.viewport.offsetTop + this.viewport.clientHeight - this.captions_height)+"px";
    }

    this.captions.style.height      = "0";
    this.captions.style.visibility  = "visible";

    this.caption        = document.createElement("H2");
    this.caption_date   = document.createElement("SPAN");
    this.caption_link   = document.createElement("A");
    this.caption_date.className = "date";
    this.caption_link.appendChild(this.caption);
    this.captions.appendChild(this.caption_date);
    this.captions.appendChild(this.caption_link);

};

Cascade.prototype.show_error = function(e) {
    if (!this.captions) {
        this.show_captions();
    }
    if (this.viewport.clientHeight == 0 && this.proportions) {
        this.viewport.style.height = "100px";
    }
    if (!this.caption) {
        this.init_captions();
    }
    obj = { caption: e.statusMessage, caption_url: '', caption_date: ''};
    if (e.status == 404) {
        obj.caption = "No data";
    } 
    this.update_caption(obj);
};

Cascade.prototype.crop_to = function(proportions) {
    this.proportions    = proportions;
};

Cascade.prototype.fit_to = function(dim, size) {
    if (!size) {
        if (dim == "width") {
            size = this.viewport.clientWidth;
        } else {
            size = this.viewport.clientHeight;
        }
    }
    this.fit = function(picture, obj) {
        if (dim == "width") {
            obj.height = Math.round(obj.height * (size / obj.width));
            if (this.proportions) {
                picture.style.marginBottom = "" + Math.round( (size * this.proportions) - obj.height ) + "px";
            }
            obj.width = size;
        } else {
            obj.width = Math.round(obj.width * (size / obj.height));
            if (this.proportions) {
                picture.style.marginRight = "" + Math.round( (size * this.proportions) - obj.width ) + "px";
            }
            obj.height = size;
        }
        picture.style.width = ""+(obj.width)+"px";
        picture.style.height = ""+(obj.height)+"px";
        return obj.width;
    };
};

Cascade.prototype.width      = function() {
    return this.canvas.clientWidth;
};

Cascade.prototype.fill       = function() {
    var fill_canvas = function(o) {
        obj     = eval("("+o.responseText+")");
        this.place(obj);
        if (this.width() < this.viewport.clientWidth) {
            this.fetch_one(fill_canvas);
        } else {
            this.init_osd();
            if (this.captions) {
                this.init_captions();
            }
            this.scroll();
        } 
    };
    this.fetch_one(fill_canvas);
};

Cascade.prototype.show_osd   = function() {
    if (this.prev && this.next) {
        if (this.running) {
            if (this.direction == CASCADE_RIGHT) {
                this.prev.style.display     = "block";
                this.next.style.display     = "none";
            } else {
                this.next.style.display     = "block";
                this.prev.style.display     = "none";
            }
        } else {
            if (this.current == 0) {
                this.prev.style.display     = "none";
            } else {
                this.prev.style.display     = "block";
            }
            if (this.max && this.latest(this.current)) {
                this.next.style.display     = "none";
            } else {
                this.next.style.display     = "block";
            }
        }
    }
};

Cascade.prototype.hide_osd   = function() {
    if (this.prev && this.next && this.running) {
        this.next.style.display     = "none";
        this.prev.style.display     = "none";
    }
};

Cascade.prototype.init_osd   = function() {
    this.next   = document.createElement("DIV");
    this.next.className         = "next";
    this.next.style.position    = "absolute";
    this.next.style.cursor      = "pointer";
    this.next.style.visibility  = "hidden";
    YAHOO.util.Dom.insertBefore(this.next, this.scroller);
    this.next.style.marginLeft  = "" + (this.viewport.clientWidth - this.next.clientWidth - 10) + "px";
    this.next.style.marginTop   = "" + ((this.viewport.clientHeight / 2) - (this.next.clientHeight / 2)) + "px";
    this.next.style.display     = "none";
    this.next.style.visibility  = "visible";

    this.prev   = document.createElement("DIV");
    this.prev.className         = "previous";
    this.prev.style.position    = "absolute";
    this.prev.style.cursor      = "pointer";
    this.prev.style.visibility  = "hidden";
    YAHOO.util.Dom.insertBefore(this.prev, this.scroller);
    this.prev.style.marginLeft  = "10px";
    this.prev.style.marginTop   = "" + ((this.viewport.clientHeight / 2) - (this.prev.clientHeight / 2)) + "px";
    this.prev.style.display     = "none";
    this.prev.style.visibility  = "visible";

    YAHOO.util.Event.addListener(this.prev, "click", function() { this.direction = CASCADE_LEFT; if (!this.running) { this.scroll(); } this.show_osd(); }, null, this);
    YAHOO.util.Event.addListener(this.next, "click", function() { this.direction = CASCADE_RIGHT; if (!this.running) { this.scroll(); } this.show_osd(); }, null, this );

};

Cascade.prototype.pause      = function () {
    this.running = false;
    this.scroll_anim.onComplete.unsubscribeAll();
    this.scroll_anim.stop();
    this.current -= this.direction;
    this.show_osd();
};

Cascade.prototype.resume     = function() {
    this.running = true;
    this.scroll();
};

Cascade.prototype.toggle     = function() {
    if (this.running) {
        this.pause();
    } else {
        this.resume();
    }
    this.show_osd();
};

Cascade.prototype.init       = function() {
    this.fill();
    YAHOO.util.Event.addListener(this.viewport, "mouseover", function() { this.show_osd(); }, null, this);
    YAHOO.util.Event.addListener(this.viewport, "mouseout", function() { this.hide_osd(); }, null, this);
    YAHOO.util.Event.addListener(this.scroller, "click", function() { this.toggle(); }, null, this);
};

Cascade.prototype.start      = function() {
    this.running    = true;
    this.init();
};

Cascade.prototype.update_caption = function (obj) {
    this.caption.innerHTML = obj.caption;
    if (this.caption_date) {
        this.caption_date.innerHTML = obj.caption_date;
    }
    this.caption_link.href = obj.caption_url;
    var anim2 = new YAHOO.util.Anim(this.captions, { top: { by: -1*this.captions_height }, height: { to: this.captions_height } }, 0.5, YAHOO.util.Easing.backOut);
    anim2.animate();
};

Cascade.prototype.swap_captions      = function() {
    obj     = this.pictures[this.current];
    if (this.caption && this.caption.textContent != obj.caption) {
        var anim = new YAHOO.util.Anim(this.captions, { top: { by: this.captions_height}, height: { to: 0 } }, 0.5, YAHOO.util.Easing.backIn );
        anim.onComplete.subscribe( function(e) { this.update_caption(obj) } , null, this);
        anim.animate();
    }
};

Cascade.prototype.scroll_to_current  = function(repeat) {
    obj     = this.pictures[this.current];
    this.scroll_anim    = new YAHOO.util.Scroll(this.scroller, { scroll: {to: [obj.left,0] } }, 4.0, YAHOO.util.Easing.easeBoth);
    if (repeat) {
        this.scroll_anim.onComplete.subscribe(repeat, null, this);
    }
    this.scroll_anim.animate();
    if (this.captions) {
        this.swap_captions();
    }
};

Cascade.prototype.latest     = function(index) {
    ret = true;
    if (index < this.pictures.length) {
        distance_to_edge = (this.pictures[this.pictures.length-1].right - this.pictures[index].right);
        ret = distance_to_edge < this.viewport.clientWidth;
    }
    return ret;
};

Cascade.prototype.scroll     = function() {
    repeat  = false;
    if (this.running) {
        repeat = function() { this.scroll(); };
    }

    var scroll_fetch = function(o) {
        obj     = eval("("+o.responseText+")");
        this.place(obj);
        if (this.direction == CASCADE_RIGHT && this.latest(this.current)) {
            if (this.max && this.pictures.length == this.max) {
                repeat = false;
                this.running = false;
                this.direction = CASCADE_LEFT;
                this.show_osd();
            } else {
                this.fetch_one(scroll_fetch);
            }
        } else {
            this.scroll_to_current(repeat);
        }
    };

    this.current += this.direction;
    if (this.current == 0) {
        this.direction = CASCADE_RIGHT;
        repeat = false;
        this.running = false;
        this.current = 0;
        this.show_osd();
        this.scroll_to_current(repeat);
    } else if (this.latest(this.current) && this.direction==CASCADE_RIGHT) {
        if (this.max && this.pictures.length == this.max) {
            repeat = false;
            this.running = false;
            this.direction = CASCADE_LEFT;
            this.show_osd();
            this.scroll_to_current(false);
        } else if (!this.max || this.pictures.length != this.max) {
            this.fetch_one(scroll_fetch);
        }
    } else {
        this.scroll_to_current(repeat);
    }
};

Cascade.prototype.set_height = function(height) {
    this.height = height;
    this.viewport.style.height = ""+(height)+"px";
    this.scroller.style.height = ""+(height)+"px";
};

