/**
 * div: id of the container element
 * example: slider_carousel('slider-carousel-top', { load_url: 'http://dfd' });
 * requirement: Scriptalous Effect
 *
 */

function slider_carousel(sldr, options) {
	var sldr = $(sldr);
	var ul = sldr.select('ul').first();
	var clip = sldr.select('div.clip').first();
	var li_count = 0; // li_count: updated dynamically, s. bellow
	var li_width = 0;
	var next = sldr.select('div.next-arrow').first();
	var prev = sldr.select('div.prev-arrow').first();
	var clip_width = sldr.getWidth() - next.getWidth() - prev.getWidth(); // webkit fix
	var data_empty = '<status>{"status":"ok","complete":false,"offers":[]}</status>';
	var ajax_count = 0;
	var ajax_count_max = 1; // absolute max
	var ajax_started = false;

	ul.setStyle({left: '0px'});
	clip.setStyle({width: clip_width + 'px'}); // webkit fix

	//clip.setStyle({position: 'absolute', margin: '0', top: prev.cumulativeOffset().top + 'px', left: clip.cumulativeOffset().left + 'px'}); // for ie6
	var tmp = clip.cumulativeOffset().top - prev.cumulativeOffset().top;
	if(tmp > 5) // for ie6
		clip.setStyle({top: '-' + tmp + 'px'});

	var searchicon = sldr.select('.searchicon').first();
	if(searchicon) {
		searchicon.position = (function() {
			this.setStyle({top: (sldr.getHeight()-this.getHeight())/2+'px', left: (sldr.getWidth()-this.getWidth())/2+'px'});
		}).bind(searchicon);

		searchicon.position();
	}

	options = options || {};
	options.duration = options.duration || 0.5;
	options.ajax_params = options.ajax_params || '';
	options.data_initial = options.data_initial || data_empty;
	options.img_size = options.img_size || {width: 98, height: 140}

	queue_scope_hover = 'queue_slider_carousel_' + Math.random();
	queue_scope_click = 'queue_slider_carousel_' + Math.random();

	var cancel_effects = function(queue_scope) {
		if(queue_scope) {
			Effect.Queues.get(queue_scope).each(function(effect) { effect.cancel(); });
			return;
		}

		Effect.Queues.get(queue_scope_hover).each(function(effect) { effect.cancel(); });
		Effect.Queues.get(queue_scope_click).each(function(effect) { effect.cancel(); });
	}

	var is_effect_running = function(queue_scope) {
		var is_running = false;
		Effect.Queues.get(queue_scope).each(function(effect) { is_running = true });
		return is_running;
	}

	var error = function(msg) {
		if(searchicon) {
			searchicon.addClassName('searchicon-noicon');
			searchicon.update(msg);
			searchicon.show();
			searchicon.position();
		} else
			alert(searchicon);
	}

	var load_ajax = function(callback) {
		if(! options.load_url || ajax_count >= ajax_count_max || ajax_started) return; // be silent
		if(searchicon) {
			searchicon.show();
			searchicon.position();
		}
		ajax_count = ajax_count + 1;
		ajax_started = true;

		var params = '?' + 'start=' + (li_count+1) + '&range=' + Math.ceil(clip_width/(li_width||options.img_size.width)) + '&' + options.ajax_params;

		new Ajax.Request(options.load_url + params, {
			method: 'get',
			// requestHeaders: {Accept: 'application/json'},
			onSuccess: function(transport) {
				if(searchicon) searchicon.hide();
				load(transport.responseText || data_empty);
				if(callback) callback();
			},
			onComplete: function() {
				ajax_started = false;
			},
			onFailure: function() { error("Network error occured."); }
		});
	}

	// is loaded and ready?
	sldr.ready = function() {
		return ! ajax_started;
	}

	var load = function(html) {
		var data = html.replace(/[\r\n]+/g, ' ');
		data = data.match(/<status>(.*?)<\/status>/);
		if(! data) throw new Error("update: no status in input data");
		data = data[1].evalJSON(true);
		// console.log('data', data); // debug

		if(data.status != 'ok') {
			error(data.status || html.stripTags());
		}

		if(data && 'offers' in data) {
			var tpl = data.tpl || {};
			tpl.li_innerHTML = new Template(tpl.li_innerHTML || '#{aimg}');
			tpl.aimg = new Template('<a class="cover" href="#{url}" title="#{title}" #{aattr}><img alt="#{title}" src="#{image_url}" /></a>');

			data.offers.each(function(offer) {
				var li = new Element('li');
				offer.aattr = tpl.aattr || '';
				offer.title = (offer.title || '').escapeHTML();
				offer.aimg = tpl.aimg.evaluate(offer);
				li.update(tpl.li_innerHTML.evaluate(offer));
				ul.appendChild(li);
			});

			li_count = ul.select('li').length || 0;

			if(li_count != 0) {
				li_width = ul.select('li').first().getWidth() || 0;
				ul.setStyle({'width': li_width*li_count+li_width+'px'});
			}
		}
	}

	load(options.data_initial);
	if(li_count == 0) load_ajax();

	var style_left_abs = function(el) {
		return Math.abs(parseFloat(el.getStyle('left').replace('px', '')))
	}

	var morph = function(left, duration, queue_scope) {
		if(left < 0) return;
		queue_scope = queue_scope || queue_scope_click;

		new Effect.Morph(ul, {
			style: {left: '-'+ left +'px'},
			transition: Effect.Transitions.linear, // sinoidal
			duration: duration, queue: { scope: queue_scope }
		});
	}

	next.observe('mouseover', function(event) {
		cancel_effects();
		morph(li_width*li_count-clip_width,
			options.duration * (li_width * li_count - style_left_abs(ul) - clip_width) / li_width, queue_scope_hover);
	});

	prev.observe('mouseover', function(event) {
		cancel_effects();
		morph(0, options.duration*style_left_abs(ul)/li_width, queue_scope_hover);
	});

	next.observe('mouseout', function(event) {
		cancel_effects(queue_scope_hover);
		if(is_effect_running(queue_scope_click))
			return;

		var go_to = Math.ceil(style_left_abs(ul) / li_width) * li_width;
		if(Math.abs(go_to - style_left_abs(ul)) > 4)
			morph(go_to, options.duration, queue_scope_hover);
	});
	prev.observe('mouseout', function(event) {
		cancel_effects(queue_scope_hover);
		if(is_effect_running(queue_scope_click))
			return;

		var go_to = Math.floor(style_left_abs(ul) / li_width) * li_width;
		if(Math.abs(go_to - style_left_abs(ul)) > 4)
			morph(go_to, options.duration, queue_scope_hover);
	});

	var next_click = function(event) {
		var limit = li_width*li_count-clip_width;
		var go = style_left_abs(ul)+clip_width;

		if(li_width*li_count - go < li_width/2) {
			//load(options.data_initial); next_click();
			load_ajax(next_click);
			return;
		}

		cancel_effects();
		morph(Math.min(limit, go), options.duration * 1.5, queue_scope_click);
	}

	next.observe('click', next_click);

	prev.observe('click', function(event) {
		var limit = 0;
		var go = style_left_abs(ul)-clip_width;

		cancel_effects();
		morph(Math.max(limit, go), options.duration * 1.5, queue_scope_click);
	});

	return sldr;
}


