/*
 * $Id: slideshow.js 9 2007-05-21 17:26:21Z ben $
 */
/*
 * $Author: ben $
 */

var debug = $.browser.msie;


/// Overrides for image classes.
/** 
 * This is a global object used as a base
 * for all the images in the slide show.
 * All the transition code should go here,
 * including wrappers around built-in transitions.
 */
var cms_slide_image_class =
{
    pre_loader : new Image(),
    /** Wrapper around the built-in JQuery FadeIn
     *  transition.
     */
    fadeIn     : function(delay, callback)
    {
	$(this).fadeIn(delay, callback);
    },
    /** Wrapper around the built-in (and really cheesy)
     *  JQuery slideDown transition (which doesn't really
     *  slide down).
     */
    grow      : function(delay, callback)
    {
	$(this).slideDown(delay, callback);
    },
    /**
     * Custom transition in which the new image
     * slides in from the right hand side of the
     * frame without distortion.
     */
    slideLeft : function(delay, callback)
    {
	$(this).css("left",this.parentNode.width + "px");
	$(this).animate({'left': 0},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * slides in from the left hand side of the
     * frame without distortion.
     */
    slideRight : function(delay, callback)
    {
	$(this).css("left","-" + this.parentNode.width + "px");
	$(this).animate({'left': 0},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * slides down from the top hand side of the
     * frame without distortion.
     */
    slideDown : function(delay, callback)
    {
	$(this).css("top","-" + this.parentNode.height + "px");
	$(this).animate({'top': 0},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * slides up from the bottom hand side of the
     * frame without distortion.
     */
    slideUp : function(delay, callback)
    {
	$(this).css("top",this.parentNode.height + "px");
	$(this).animate({'top': 0},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * grows right from the left hand side of the
     * frame.
     */
    expandRight : function(delay, callback)
    {
	$(this).css("width",  "0px");
	$(this).css("height", this.parentNode.height + "px");
	$(this).animate(
	{
	    'width': new Number(this.parentNode.width),
	    'height': new Number(this.parentNode.height)
	},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * grows left from the right hand side of the
     * frame.
     */
    expandLeft : function(delay, callback)
    {
	$(this).css("width",  "0px");
	$(this).css("height", this.parentNode.height + "px");
	$(this).css("left",   this.parentNode.width  + "px");
	$(this).animate(
	{
	    'width': new Number(this.parentNode.width),
	    "height": new Number(this.parentNode.height),
	    "left": 0
	},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * grows down from the top hand side of the
     * frame.
     */
    expandDown : function(delay, callback)
    {
	$(this).css("width", this.parentNode.width + "px");
	$(this).css("height", "0px");
	$(this).animate({'width': new Number(this.parentNode.width),
			 "height": new Number(this.parentNode.height)},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * grows up from the bottom hand side of the
     * frame.
     */
    expandUp : function(delay, callback)
    {
	$(this).css("width", this.parentNode.width + "px");
	$(this).css("height", "0px");
	$(this).css("top",   this.parentNode.height + "px");
	$(this).animate({'width': new Number(this.parentNode.width),
			 "height": new Number(this.parentNode.height), "top": 0},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * grows from a horizontal line in the middle 
     * of the frame, both up and down until it fills
     * the frame.
     */
    expandUpDown : function(delay, callback)
    {
	$(this).css("width", this.parentNode.width + "px");
	$(this).css("height", "0px");
	$(this).css("top",   this.parentNode.height/2 + "px");
	$(this).animate({'width': new Number(this.parentNode.width), "height": new Number(this.parentNode.height), "top": 0},delay,"linear",callback);
    },
    /**
     * Custom transition in which the new image
     * grows from a vertical line in the middle 
     * of the frame, both right and left until it fills
     * the frame.
     */
    expandRightLeft : function(delay, callback)
    {
	$(this).css("width","0px");
	$(this).css("height", this.parentNode.height + "px");
	$(this).css("left",   this.parentNode.width/2 + "px");
	$(this).animate({'width': new Number(this.parentNode.width), "height": new Number(this.parentNode.height), "left": 0},delay,"linear",callback);
    },
    /**
     * Begins as a single pixel in the middle of the frame and grows
     * outward, preserving its aspect ratio.
     */
    expandOut : function(delay, callback)
    {
	$(this).css("width","0px");
	$(this).css("height", "0px" );
	$(this).css("left",   this.parentNode.width/2 + "px");
	$(this).css("top",    this.parentNode.height/2 + "px");
	$(this).animate({'width': new Number(this.parentNode.width), "height": new Number(this.parentNode.height), "left": 0, "top":0},delay,"linear",callback);
    },
    /**
     * Combines a fade-in with an initially oversized image that shrinks
     * to the correct size.
     * In this transition, the image is initially centered.
     */
    contractC : function(delay, callback)
    {
	$(this).css("width",  this.parentNode.width * 2 + "px");
	$(this).css("height", this.parentNode.height * 2  + "px");
	$(this).css("left",   "-" + (this.parentNode.width/2) + "px");
	$(this).css("top",    "-" + (this.parentNode.height/2) + "px");
	$(this).css("opacity", 0);
	$(this).animate({opacity: 1, 'width': new Number(this.parentNode.width), "height": new Number(this.parentNode.height), "left": 0, "top":0},delay,"linear",callback);
    },
    /**
     * Combines a fade-in with an initially oversized image that shrinks
     * to the correct size.
     * In this transition, the image is initially aligned to the Top Left.
     */
    contractFromTL : function(delay, callback)
    {
	$(this).css("width",  this.parentNode.width * 2 + "px");
	$(this).css("height", this.parentNode.height * 2  + "px");
	$(this).css("opacity", 0);
	$(this).animate({opacity: 1, 'width': new Number(this.parentNode.width), "height": new Number(this.parentNode.height), "left": 0, "top":0},delay,"linear",callback);
    },
    /**
     * Combines a fade-in with an initially oversized image that shrinks
     * to the correct size.
     * In this transition, the image is initially aligned to the Top Right.
     */
    contractFromTR : function(delay, callback)
    {
	$(this).css("width",  this.parentNode.width * 2 + "px");
	$(this).css("height", this.parentNode.height * 2  + "px");
	$(this).css("left",   "-" + (this.parentNode.width) + "px");
	$(this).css("opacity", 0);
	$(this).animate({opacity: 1, 'width': new Number(this.parentNode.width), "height": new Number(this.parentNode.height), "left": 0, "top":0},delay,"linear",callback);
    },
    /**
     * Combines a fade-in with an initially oversized image that shrinks
     * to the correct size.
     * In this transition, the image is initially aligned to the Bottom Left.
     */
    contractFromBL : function(delay, callback)
    {
	$(this).css("width",  this.parentNode.width * 2 + "px" );
	$(this).css("height", this.parentNode.height * 2 + "px");
	$(this).css("top",    "-" + (this.parentNode.height) + "px");
	$(this).css("opacity", 0);
	$(this).animate({opacity: 1, 'width': new Number(this.parentNode.width), "height": new Number(this.parentNode.height), "left": 0, "top":0},delay,"linear",callback);
    },
    /**
     * Combines a fade-in with an initially oversized image that shrinks
     * to the correct size.
     * In this transition, the image is initially aligned to the Bottom Right.
     */
    contractFromBR : function(delay, callback)
    {
	$(this).css("width",  this.parentNode.width * 2+ "px");
	$(this).css("height", this.parentNode.height * 2 + "px");
	$(this).css("left",   "-" + (this.parentNode.width) + "px");
	$(this).css("top",    "-" + (this.parentNode.height) + "px");
	$(this).css("opacity", 0);
	$(this).animate({opacity: 1, 'width': new Number(this.parentNode.width), "height": new Number(this.parentNode.height), "left": 0, "top":0},delay,"linear",callback);
    }
};

var cms_slideshow_class =
{
    first_image    : 0,
    delay        : 1,
    transition   : 'fadeIn',
    trans_dur    : 500,
    order        : 'quick',
    ready_images : new Array(),
    idx          : 0,
    state        : 'stopped',
    on_image     : null,
    height       : 640,
    width        : 480,
    total		 : 0,

    show_next : function() {
		var image;
		var delay      = this.delay;
		var trans_dur  = this.trans_dur;
		var transition = this.transition;
		if (this.order == 'shuffle') {
			image    = this.ready_images[this.idx];
		} else if (this.order == 'strict') {
			image    = $(this).children("img")[this.idx];
		} else {
			image    = this.ready_images[this.idx];
		}
		if (!image || !image.ready) {
			this.status = 'stopped';
			return;
		}
		$(image).css('display','block');
		if (image.id) {
			var image_params = $("input[@name=target_image_id]").filter("input[@value=" + (image.id) + "]").parent();
			if (image_params.length) {
			var vd = image_params.children("[@name=delay]").val();
			var td = image_params.children("[@name=trans_dur]").val();
			var ts = image_params.children("[@name=transition]").val();
			var u = image_params.children("[@name=url]").val();
			if (vd) delay = vd;
			if (td) trans_dur = td;
			if (ts) transition = ts;
			var url = u;
			cms_debug(image.id + " delay: " + delay + " trans_dur: " + trans_dur + " transition: " + transition + " url: " + url);
			}
		}
		$(image).css('z-index',99);
		if (url) {
			$(image).css('cursor','pointer');
			$(image).click(function() {location.href=url});
		}
		eval('image.' + transition + '(new Number(' + trans_dur + '),function(){ if ( this.parentNode.on_image ) { $(this.parentNode.on_image).css("display","none");} this.parentNode.on_image = this;});');
		if (this.on_image) {
			$(this.on_image).css('z-index', 1);
		}
		
		if (this.order == 'shuffle') {
			var newidx = Math.floor(Math.random() * this.ready_images.length);
			if ((newidx) == (this.idx)) {
			newidx++;
			newidx %= this.ready_images.length;
			}
			this.idx = newidx;
		} else if (this.order == 'strict') {
			this.idx++;
			this.idx %= $(this).children("img").length;
		} else {
			this.idx++;
			this.idx %= this.ready_images.length;
		}
		$(this).animate({'visible':'show'},delay * 1000,"",function(){ this.show_next(false); });
	},

    add_ready_image : function(image) {
		this.ready_images.push(image);
    }
};

function cms_debug(message)
{
    var cms_slideshow_debug = $("#cms_slideshow_debug");
    if (!cms_slideshow_debug) return;
    cms_slideshow_debug.prepend("<div>" + message + "</div>");
}
var debug = true;


function cms_slideshow_start(show)
{
    var images;
    show.idx = show.first_image;
    if (show.idx == undefined) show.idx = 0;
    show.state = 'stopped';
    images = $(show).children("img");
    show.total = images.length;
    images.each(function(item) {
    	$.extend(this,cms_slide_image_class);    	
		//$(this).load(function() {
			show.add_ready_image(this);
			this.ready = true;
			if (show.ready_images.length == show.total) {
				show.state = 'started';
				show.show_next(true);
			}
		//});
    });    
}

function cms_slideshows_init()
{
    cms_debug("In cms_slideshows_init()");
    $(".cms_slideshow").each(function(show){
		$.extend(this, cms_slideshow_class);
		var params = $(this).children("div.cms_params");
		params.children('input').each(
			function (param) {
			var show = this.parentNode.parentNode;
			switch(this.name) {
				case 'first_image'  : show.first_image  = this.value; break;
				case 'delay'      : show.delay      = this.value; break;
				case 'transition' : show.transition = this.value; break;
				case 'order'      : show.order      = this.value; break;
				case 'height'     : show.height     = this.value; break;
				case 'width'      : show.width      = this.value; break;
				//case 'bgcolor'    : show.bgcolor    = this.value; break;
				case 'trans_dur'  : show.trans_dur  = this.value; break;
			}
			}
		)
		$(this).wrap("<div class=\"cms_slideshow_wrapper\"></div>");
		var w = $(this).parent();
		$(this).css('width',this.width + "px");
		$(this).css('height',this.height + "px");
		//$(this).css('background-color', this.bgcolor);
		w.css('width',this.width + "px");
		w.css('height',this.height + "px");
		cms_debug(this.width);
		
		// show the first image
		cms_slideshow_start(this);
		});
}

$(document).ready(cms_slideshows_init);
