dojo.provide('csitko.widget.Carousel');

dojo.declare("csitko.widget.Carousel", [], {
	items: [],
	width: 0,
	container_width: 0,
	node: null,
	position: 0,
	min_left: 0,
	left_button: null,
	right_button: null,
	wrap: false,
	flip_count: 1,
	view_count: 3,
	row_count: 1,
	page: 1,
	pages: 1,
	class_base: null,
	moving: false,

	ANIMATION_DURATION: 700,
	constructor: function(class_base, view_count, flip_count, wrap, hide_buttons, row_count)
	{
	if (!view_count)
		this.view_count = 3;
	else
		this.view_count = view_count;
	if (!flip_count)
		this.flip_count = this.view_count;
	else
		this.flip_count = flip_count;
	if (!wrap)
		this.wrap = false;
	else
		this.wrap = wrap;
	if (!hide_buttons)
		hide_buttons = false;
	if (!row_count)
		this.row_count = 1;
	else
		this.row_count = row_count;
	
	this.class_base = class_base;
	
	var containers = dojo.query("." + class_base + "-container");
	if (containers.length == 1)
		this.node = containers[0];
	else
		return;
	dojo.style(this.node, {position: 'relative'});
	
	try{
		this.left_button = dojo.query("." + class_base + "-left")[0];
		dojo._setOpacity(this.left_button, .5);
	} catch(e){}

	try{
		this.right_button = dojo.query("." + class_base + "-right")[0];
	} catch(e){};

    // Only grab the child list-items (children of each of these could also
    // contain list items, but should not be considered for this purpose)
	this.items = dojo.query('> li', this.node);

    this.pages = Math.ceil((this.items.length/this.row_count)/this.flip_count);

	this.width = dojo.marginBox(this.items[0]).w;
	if (dojo.isSafari)
	{
		// fix for dojo's inability to properly get the marginBox
		// on safari if the left and right margins differ
		var css = dojo.getComputedStyle(this.items[0]);
		var marginRight = dojo._toPixelValue(this.items[0], css.marginRight);
		var marginLeft = dojo._toPixelValue(this.items[0], css.marginLeft);
		this.width += marginRight - marginLeft;
	}

	if (this.width == 0)
	{
		var hiddenStyle = dojo.style(this.items[0]);
		this.width = this.make_int(hiddenStyle.width)
				+ this.make_int(hiddenStyle.marginLeft) 
				+ this.make_int(hiddenStyle.marginRight) 
				+ this.make_int(hiddenStyle.paddingLeft)
				+ this.make_int(hiddenStyle.paddingRight);
	}
	
	if (this.items.length <= this.view_count && hide_buttons)
	{
		dojo.style(this.left_button, {visibility: 'hidden'});
		dojo.style(this.right_button, {visibility: 'hidden'});
	} else {
		dojo.style(this.left_button, {visibility: 'visible'});
		dojo.style(this.right_button, {visibility: 'visible'});
	}

	this.min_left = -1 * this.width * (this.items.length/this.row_count - this.view_count);
	this.min_left = (Math.min(this.min_left, 0));

	var total_width = (this.width * this.items.length + 50)/this.row_count;
	
	dojo.style(this.node, {width: total_width + 'px'});
	this.container_width = total_width;
	
	if (this.left_button)
	{
		dojo.style(this.left_button, {cursor: 'pointer'});
		dojo.connect(this.left_button, 'onclick', this, this.scroll_left);
	}

	if (this.right_button)
	{
		dojo.style(this.right_button, {cursor: 'pointer'});
		dojo.connect(this.right_button, 'onclick', this, this.scroll_right);
	}

	// add blank line items to fill out the final section
	var remainder = this.items.length % this.view_count;
	var blanks = 0;
	
	if (remainder > 0)
		blanks = this.view_count - remainder;

	for (var i = 0; i < blanks; i++)
    {
		dojo.create("li", {className: this.items[0].className, style: "visibility: hidden;"}, this.node);
		total_width += this.width;
		this.min_left -= this.width;
	}
	
	if (this.wrap && this.items.length > this.view_count)
	{
		for (var i = 0; i < this.view_count; i++)
		{
			var extend = dojo.clone(this.items[i]);
			dojo.place(extend, this.node);
			total_width += this.width;
			this.min_left -= this.width;
		}
	}

	dojo.style(this.node, {width: total_width + 'px'});
	this.reset();
	},

	make_int: function(str)
	{
		return str.replace(/\D/g, '') * 1;
	},

	scroll_left: function(evt)
	{
		if (evt != null)
			dojo.stopEvent(evt);

		if (this.moving || this.items.length <= this.view_count)
			return;

		if (this.wrap && this.position == 0)
		{
			this.position = this.min_left;
			dojo.style(this.node, {left: this.position + "px"});
		}
			
		if (this.position < 0)
		{
			this.scroll_animation(Math.min(0, this.position + (this.width * this.flip_count)))
	        this.fix_pages(this.page - 1);
		}
	},

	scroll_right: function(evt)
	{
		if (evt != null)
			dojo.stopEvent(evt);

		if (this.moving || this.items.length <= this.view_count)
			return;
		
		if (this.position >= this.min_left)
		{
			this.scroll_animation(Math.max(this.min_left, this.position - (this.width * this.flip_count)))
	        this.fix_pages(this.page + 1);
		}
	},

	scroll_animation: function(position, wrap)
	{
		if (!wrap)
			wrap = false;

		this.position = position;

		this.fix_buttons();

		if (this.wrap && (this.position == this.min_left))
			on_end = dojo.hitch(this, this.reset);
		else
			on_end = dojo.hitch(this, function(){this.moving = false;});

		dojo.anim(this.node, {left: position}, this.ANIMATION_DURATION, null, on_end);
		this.moving = true;
	},

	fix_buttons: function()
	{
		if (!this.wrap && this.position == 0)
			dojo._setOpacity(this.left_button, .5)
		else
			dojo._setOpacity(this.left_button, 1)
		//if (!this.wrap && (this.position - this.width) == this.min_left)
		if (!this.wrap && this.position == this.min_left)
			dojo._setOpacity(this.right_button, .5)
		else
			dojo._setOpacity(this.right_button, 1)
	}, 

    fix_pages: function(page)
    {
        // set counter
		this.page = Math.max(0, Math.min(page, this.pages));

		// get nodes by class 
        var scroll_span_id = this.class_base + '-pages';
        var page_nodes = dojo.query('li', scroll_span_id);

        // - set all off
        page_nodes.removeClass('agi-scroll-on');
        page_nodes.addClass('agi-scroll-off');

        // - set one on
        this.on_id = '#agi-scroll-page-' + (this.page-1);
        this.on_node = dojo.query('#' + this.class_base + '-page-' + (this.page), scroll_span_id);
        this.on_node.addClass('agi-scroll-on');
        this.on_node.removeClass('agi-scroll-off');
    },

    reset: function()
	{
		this.moving = false;
		this.node.style.left = '0px';
		this.position = 0;
		this.fix_pages(1);
		this.fix_buttons();
	}
});
