dkamera.vergleich = (function($) {
	var columns = {};
	var kameras = {};
	var fields_min_max = {};
	var fields = {
		//amazonpreis: 'low',
		markteinfuehrung: 'high',
		megapixel: 'high',
		bildaufloesung: 'high',
		sensor: 'high',
		serienbilder: 'high',
		bildformate: 'high',
		videoaufloesung: 'high',
		videofrequenz: 'high',
		videoeinschraenkung: 'high',
		interner_speicher: 'high',
		optischer_zoom: 'high',
		digitaler_zoom: 'high',
		akkuleistung: 'high',
		cipa: 'high',
		blende_weitwinkel: 'low',
		blende_tele: 'low',
		brennweite_weitwinkel: 'low',
		brennweite_tele: 'high',
		filtergewinde: 'high',
		schaerfebereich_makro_min: 'low',
		schaerfebereich_makro_max: 'high',
		schaerfebereich_normal_min: 'low',
		schaerfebereich_normal_max: 'high',
		belichtungszeit_von: 'high',
		belichtungszeit_bis: 'low',
		displaygroesse: 'high',
		displayaufloesung: 'high',
		suchervorhanden: 'high',
		bildstabilisator_integriert: 'high',
		bildstabilisator_objektiv: 'high',
		belichtungssteuerung: 'high',
		belichtungsreihe: 'high',
		weissabgleich: 'high',
		gesichtserkennung: 'high',
		blitz: 'high',
		blitzschuh: 'high',
		monitor_klappbar: 'high',
		monitor_drehbar: 'high',
		stativgewinde: 'high',
		liveview: 'high',
		groesse: 'low',
		//gewicht: 'low',
		fokussierung: 'high',
		iso_min: 'low',
		iso_max: 'high',
		usb_version: 'high',
		bildaufloesung: 'high'
	}
	
	var $dbv = null;
	
	function _field_min_max(name)
	{
		if (fields_min_max[name])
			return fields_min_max[name];
		var min = null;
		var max = null;
		$.each(columns, function (i, pk) {
			//dkamera.log(['pk', pk]);
			if (!pk) return;
			var data = kameras[pk];
			if (!data) return;
			var kamera = data.kamera;
			if (!kamera) return;
			if (typeof kamera.fields[name] != 'undefined')
			{
				var value = kamera.fields[name];
				//dkamera.log(['min_max', name, kamera, min, max, value]);
				//dkamera.log(value);
				if (min == null || min > value)
					min = value;
				if (max == null || max < value)
					max = value;
			}
		});
		fields_min_max[name] = [min, max];
		return [min, max];
	}
	
	function _fields_min_max()
	{
		$.each(fields, function (name, type) {
			fields_min_max[name] = _field_min_max(name);
		});
		return fields_min_max;
	}
	
	function _clear_fields_min_max()
	{
		fields_min_max = {};
	}
	
	function _highlight_column(i)
	{
		var pk = columns[i];
		if (!pk) return;
		var data = kameras[pk];
		if (!data) return;
		var kamera = data.kamera;
		if (!kamera) return;
		var fields_min_max = _fields_min_max();
		var $column = $dbv.find('.column-' + i);
		$.each(fields, function (name, compare) {
			var result = 'undefined';
			if (typeof kamera.fields[name] != 'undefined' && fields_min_max[name])
			{
				var min = fields_min_max[name][0];
				var max = fields_min_max[name][1];
				var value = kamera.fields[name];
				result = 'tie';
				if (min != max)
				{
					if (value == min) {
						if (compare == 'low')
							result = 'best';
						else if (compare == 'high')
							result = 'worst';
					}
					if (value == max) {
						if (compare == 'low')
							result = 'worst';
						else if (compare == 'high')
							result = 'best';
					}
				}
			}
			var $field = $column.find('.' + name);
			$field.removeClass('best tie worst undefined');
			$field.addClass(result);
			var $td = $field.parents('td');
			if ($field.hasClass('ignore_highlight_cell')) return;
			$td.removeClass('best tie worst undefined');
			if ($td.find('div.' + name).length)
				$td.addClass(result);
			if (!$td.find('.data:not(.' + result + '):not(:empty):not(.ignore_highlight_cell)').length)
				$td.addClass(result);
		});
	}
	
	function _highlight_columns()
	{
		$.each(columns, function (i, pk) {
			_highlight_column(i);
		});
	}
	
	function _hide_empty_rows()
	{
		$dbv.find('> table > tbody > tr:not(:has(> th))').each(function (i, tr) {
			var $tr = $(tr);
			if ($tr.find('td:has(div)').length)
				$tr.show();
			else
				$tr.hide();
		});
	}
	
	function _hide_empty_headline_rows()
	{
		$dbv.find('> table > tbody > tr:has(> th)').each(function (i, tr) {
			var $tr = $(tr);
			var found = false;
			var $next = $tr.next();
			while ($next.length && $next.is(':not(:has(> th))') && !found)
			{
				//if ($next.is(':visible')) found = true;
				if ($next.find('td:has(div)').length) found = true;
				$next = $next.next();
			}
			if (found)
				$tr.show();
			else
				$tr.hide();
		});
	}
	
	function load_column(i, pk, handle_change, callback)
	{
		if (typeof handle_change == 'undefined') var handle_change = true;
		if (typeof callback == 'undefined') var callback = function (i, pk, data) { /* empty */ };
		var _handle_data = function (data) {
			$.each(data.html, function (selector, html) {
				var $td = $dbv.find(selector + ' .column-' + i);
				$td.removeClass('best tie worst');
				$td.html(html);
			});
			_init_column(i);
			if (handle_change)
			{
				_clear_fields_min_max();
				_highlight_columns();
				_update_link();
				_update_fehlerreport();
				_set_history();
				_log_selection();
				_hide_empty_rows();
				_hide_empty_headline_rows();
				if (typeof reload_ads != 'undefined') reload_ads();
			}
			callback(i, pk, data);
		};
		var data = kameras[pk];
		if (!data)
		{
			$.each(kameras, function (i, d) {
				if (d.kamera.slug == pk)
					data = d;
			});
		}
		if (!data)
		{
			$.getJSON('/digitalkamera-vergleich/ajax/load/' + pk, null, function(data, status) {
				if (status != 'success') return;
				columns[i] = data.kamera.pk;
				kameras[data.kamera.pk] = data;
				_handle_data(data);
			});
		}
		else
		{
			columns[i] = data.kamera.pk;
			_handle_data(data);
		}
	}
	
	function unload_column(i, handle_change, callback)
	{
		if (typeof handle_change == 'undefined') var handle_change = true;
		if (typeof callback == 'undefined') var callback = function (i) { /* empty */ };
		columns[i] = null;
		$dbv.find('.column-' + i).empty().removeClass('best tie worst');
		$dbv.find('.select .column-' + i).html('<div class="roundbutton"><a class="select-kamera">Kamera wählen</a></div>');
		$dbv.find('.bild .column-' + i).html('<div class="select-kamera"><img src="/media/bilder/kamerauebersicht/dummy.jpg" alt="" /></div>');
		_init_column(i);
		if (handle_change)
		{
			_clear_fields_min_max();
			_highlight_columns();
			_update_link();
			_update_fehlerreport();
			_set_history();
			_log_selection();
			_hide_empty_rows();
			_hide_empty_headline_rows();
			if (typeof reload_ads != 'undefined') reload_ads();
		}
		callback(i);
	}
	
	function _init_column(i)
	{
		$elements = $dbv.find('.column-' + i);
		$elements.find('.select-kamera').bind('click', function () {
			dkamera.kamera.selector.open('/digitalkamera-vergleich/ajax/search', function (kamera) {
				var loading = dkamera.loading.start($dbv);
				load_column(i, kamera.pk, true, function () {
					loading.stop();
				});
			});
		});
		var $bild_row = $dbv.find('.bild');
		var $bild = $bild_row.find('.column-' + i);
		var $img = $bild.find('div:not(.infos) img')
		var $infos = $dbv.find('.hover-info .column-' + i + ' .infos');
		var $text = $infos.find('.text');
		$text.css({
			marginTop: - ($text.height() / 2) + 'px',
		});
		$img.hover(
			function () {
				/*
				$infos.css({
					height: ($bild_row.height() - 1) + 'px',
					width: ($bild_row.width() - 1) + 'px',
					top: $bild.position().top + 'px', // IE does not like $bild_row here
					left: $bild_row.position().left + 'px'
				});
				*/
				$infos.css({
					height: ($bild.outerHeight() - 1) + 'px',
					width: ($bild.outerWidth() - 1) + 'px',
					top: $bild.position().top + 'px',
					left: $bild.position().left + 'px'
				});
				if ($infos.find('.rueckansicht').length) // TODO: Nur bei "nur Rückansicht"-Lösung
					$infos.fadeIn(300);
			},
			function () {
			}
		);
		$infos.hover(
			function () {
			},
			function () {
				$infos.stop().css('opacity', 1).hide();
			}
		);
		/*
		$bild_row.hover(
			function () {
			},
			function () {
				$infos.stop().css('opacity', 1).hide();
			}
		);
		*/
		$infos.hide();
	}
	
	function _log_selection()
	{
		var pks = '';
		$.each(columns, function (i, pk) {
			if (!pk) return;
			if (pks) pks += ',' + pk;
			else pks += pk;
		});
		if (pks)
			$.getJSON('/digitalkamera-vergleich/ajax/log/' + pks + '?anti_cache=' + Math.floor(Math.random()*99999), null, function () { /* nothing needed here? */ });
	}
	
	function _update_link() {
		/* placeholder, _update_link gets defined in _add_link_generator */
	}
	
	function _add_link_generator()
	{
		var $link_box = $('<div class="link">');
		_update_link = function () {
			var slugs = '';
			$.each(columns, function (i, pk) {
				if (!pk) return;
				var data = kameras[pk];
				if (!data) return;
				var kamera = data.kamera;
				if (!kamera) return;
				if (slugs) slugs += ',' + kamera.slug;
				else slugs += kamera.slug;
			});
			$link_box.text('/digitalkamera-vergleich/' + slugs);
		}
		$dbv.prepend($link_box);
		_update_link();
	}
	
	function _history_handler()
	{
		var hash = $.history.getCurrent();
		if (!hash) return;
		var slugs = hash.split(',');
		var index = 0;
		var done = 0;
		var may_change = false;
		var loading = dkamera.loading.start($dbv);
		var _handle_change = function (force, i) {
			if (typeof force == 'undefined') force = false;
			if (typeof i != 'undefined') done++;
			dkamera.log(['_history_handler::_handle_change', force, index, done, may_change]);
			if (!force && !may_change) return;
			if (!force && done < index) return;
			_clear_fields_min_max();
			_highlight_columns();
			_update_link();
			_update_fehlerreport();
			_hide_empty_rows();
			_hide_empty_headline_rows();
			if (typeof reload_ads != 'undefined') reload_ads();
			if (!force)
				_log_selection();
			loading.stop();
		};
		$.each(slugs, function(i, slug) {
			if (!slug) return;
			if (!$dbv.find('.column-' + i).length) return;
			if (columns[index])
			{
				var data = kameras[columns[index]];
				if (!data) return;
				var kamera = data.kamera;
				if (kamera.slug == slug)
				{
					index++;
					done++;
					return;
				}
			}
			load_column(index, slug, false, function (i) { _handle_change(false, i); } );
			index++;
		});
		var index_test = index;
		$.each(columns, function (i, pk) {
			if (index_test <= i)
			{
				unload_column(i, false, function (i) { _handle_change(false, i); } );
				index++;
			}
		});
		may_change = true;
		_handle_change();
		window.setTimeout(function () { _handle_change(true); }, 2000);
	}
	
	function _set_history()
	{
		var slugs = '';
		$.each(columns, function (i, pk) {
			if (!pk) return;
			var data = kameras[pk];
			if (!data) return;
			var kamera = data.kamera;
			if (!kamera) return;
			if (slugs) slugs += ',' + kamera.slug;
			else slugs += kamera.slug;
		});
		if (slugs)
			$.history.add(slugs);
	}
	
	function _update_fehlerreport()
	{
		var slugs = '';
		var links = [];
		$.each(columns, function (i, pk) {
			if (!pk) return;
			var data = kameras[pk];
			if (!data) return;
			var kamera = data.kamera;
			if (!kamera) return;
			if (slugs) slugs += ',' + kamera.slug;
			else slugs += kamera.slug;
			var $column = $dbv.find('.column-' + i);
			$column.find('.fehlerreport').each(function (i, el) {
				links.push($(el));
			});
		});
		var url = '/digitalkamera-vergleich/' + slugs;
		$.each(links, function (i, $link) {
			var link_url = $link.data('url');
			if (!link_url)
			{
				link_url = $link.attr('href');
				$link.data('url', link_url);
			}
			link_url += '&backurl=' + url;
			$link.attr('href', link_url);
		});
	}
	
	function init(num_columns, json_data)
	{
		dkamera.kamera.selector.init();
		$dbv = $('#datenblatt-vergleich');
		var i = 0;
		for (i = 0; i < num_columns; i++)
		{
			columns[i] = null;
			_init_column(i);
		}
		if (json_data)
		{
			$.each(json_data, function(i, data) {
				if (i > num_columns) return;
				if (data.kamera && data.kamera.pk)
				{
					columns[i] = data.kamera.pk;
					kameras[data.kamera.pk] = data;
				}
			});
			_highlight_columns();
		}
		//_add_link_generator();
		_log_selection();
		_hide_empty_rows();
		_hide_empty_headline_rows();
		//dkamera.log(['columns', columns]);
		//dkamera.log(['kameras', kameras]);
		$(document).history(_history_handler);
		if (!$.history.getCurrent())
			_set_history();
		_history_handler();
	}
	
	function debug()
	{
		dkamera.log('Spalten');
		dkamera.log(columns);
		dkamera.log('Felder Min/Max');
		dkamera.log(fields_min_max);
		dkamera.log('Kameras');
		$.each(kameras, function (i, data) {
			dkamera.log(i + '. ' + data.kamera.name);
			dkamera.log(data.kamera);
		});
	}
	
	return {
		init: init,
		load_column: load_column,
		unload_column: unload_column,
		debug: debug
	};
})(jQuery);


