// objects collection -- dirty hack
var RotatingCollection = [];
/**
 * rotating object constructor
 *
 * @param Number block_id -- ID of current rotating block
 * @param Number periodicy -- delay (in seconds) between faces
 * @param Object options -- hash map to configure or extend object. keys {
 *		jQuery countIndicator -- element to show overall face count (optional)
 *		jQuery currentIndicator -- element to show current face index (optional)
 *		jQuery controlPlay -- trigger element to toggle play
 *		jQuery controlPause -- trigger element to toggle pause
 *		jQuery controlForward -- trigger element to display next face manualy
 *		jQuery controlRew -- trigger element to display previous face manualy
 * }
 */
var Rotating = function(block_id, periodicy, options)
{
	// properties
	this.block_id = block_id;
	this.periodicy = periodicy;
	this.countIndicator = $0('nothing');
	this.currentIndicator = $0('nothing');
	this.controlPlay = $0('nothing');
	this.controlPause = $0('nothing');
	this.controlForward = $0('nothing');
	this.controlRew = $0('nothing');
	this.intervalId = null;
	this.ids = [];
	this.loaded = [];
	this.count = 0;
	this.current = -1;
	this.toLoad = -1;
	this.started = false;

	// callbacks
	this.onFlip = null;

	// configure
	if ('object' == typeof (options))
	{
		jQuery.extend(this, options);
	}
	this.controlPause.hide();

	// methods
	// overall count setter
	this.setCount = function(count)
	{
		this.count = count;
		this.countIndicator.html(count);
	};
	// current id setter
	this.setCurrent = function(current)
	{
		this.current = current;
		this.currentIndicator.html(current + 1);
	};
	// process list of faces IDs
	this.processList = function(json)
	{
		this.setCount(json.faces.length);
		this.ids = json.faces;
		for (i=0, ci=this.count; i<ci; i++)
		{
			e = $0('#face_' + this.ids[i]);
			if (e.length > 0)
			{
				this.loaded[i] = e;
				if (e.filter(':visible').length > 0)
				{
					this.setCurrent(i);
				}
			} else {
				this.loaded[i] = false;
			}
		}
		if (-1 == this.current)
		{
			this.getNext();
		}
	};
	// pull correct block from collection by ID
	this.processRespond = function(json)
	{
		// "this" is XMLHttpRequest
		var block = RotatingCollection[json.block_id];
		if ('list' == json.action)
		{
			block.processList(json);
		} else if ('load' == json.action)
		{
			block.loadFace(json);
		} else {
			alert('unknown action!');
		}
	};
	// request list of faces IDs
	this.getList = function(callback)
	{
		$0.getJSON(
			'/',
			{
				cmd: 'SSM_Rotating_Command_Block_Ajax',
				block_id: this.block_id,
				action: 'list'
			},
			this.processRespond
		);
	};
	// show/request next face
	this.getNext = function(block_id)
	{
		if ('undefined' != typeof (block_id))
		{
			return RotatingCollection[block_id].getFace(1);
		}
		return this.getFace(1);
	};
	// show/request previous face
	this.getPrev = function(block_id)
	{
		if ('undefined' != typeof (block_id))
		{
			return RotatingCollection[block_id].getFace(-1);
		}
		return this.getFace(-1);
	};
	// show/request face by step
	this.getFace = function(step)
	{
		// empty or still loading
		if (0 == this.count || this.toLoad != -1)
		{
			return false;
		}
		this.next = this.current + step;
		if (this.next >= this.count)
		{
			this.next = 0;
		} else if (this.next < 0)
		{
			this.next = this.count - 1;
		}
		if (this.checkLoaded(this.next))
		{
			this.flip();
		}
		return false;
	};
	// show/request face by number
	this.getFaceNum = function(idx)
	{
		// still loading
		if (this.toLoad != -1)
		{
			return false;
		}
		this.next = idx;
		if (this.next >= this.count)
		{
			this.next = 0;
		}
		if (this.checkLoaded(this.next))
		{
			this.flip();
		}
		return false;
	};
	this.flip = function () {
		$0('.rb_label', '#rotating_' + this.block_id).removeClass('rb_label_selected');
		$0('#label_' + this.block_id + '_' + this.next).addClass('rb_label_selected');
		this.loaded[this.current].hide();
		this.loaded[this.next].show();
		this.setCurrent(this.next);
		if ('function' == typeof(this.onFlip))
		{
			this.onFlip();
		}
	}
	// TODO
	this.loadFace = function(json)
	{
		// create div
		$0('#rotating_' + this.block_id).append('<div class="rb_face" id="face_' + this.ids[this.next] + '"></div>');
		// load contents
		this.loaded[this.next] = $0('#face_' + this.ids[this.next]).hide();
		this.loaded[this.next].html(json.face);
		this.flip();
		this.toLoad = -1;
	};
	/**
	 * if loaded return true. otherwise start to load and return false
	 *
	 * @return Boolean
	 */
	this.checkLoaded = function(num)
	{
		if (false == this.loaded[num])
		{
			this.toLoad = num;
			// request contents
			$0.getJSON(
				'/',
				{
					cmd: 'SSM_Rotating_Command_Block_Ajax',
					block_id: this.block_id,
					action: 'load',
					face_id: this.ids[num]
				},
				this.processRespond
			);
			return false;
		}
		return true;
	};
	// play/start rotation in current block
	this.toggle = function (play) {
		if ('boolean' == typeof (play))
		{
			this.started = play;
		}
		if (this.started)
		{
			if (!this.intervalId) {
				var i = this.block_id;
				this.intervalId = setInterval('RotatingCollection[' + this.block_id + '].getNext()', this.periodicy * 1000);
			}
			this.controlPause.show();
			this.controlPlay.hide();
			if ('boolean' != typeof (play)) this.started = false;
		} else {
			if (this.intervalId) {
				clearInterval(this.intervalId);
				this.intervalId = null;
			}
			this.controlPlay.show();
			this.controlPause.hide();
			if ('boolean' != typeof (play)) this.started = true;
		}
		return false;
	};

	// push itself to collection
	RotatingCollection[block_id] = this;
};