/**
 * 
 * @param {Object} local_conf
 */
List = function (local_conf) {
    if (typeof jQuery === 'undefined') {
         throw 'List exception: jQuery not found.';
    }

	//
    var conf = {};

	conf.boxId = null;

	conf.listAjaxUrl = null;
	conf.params = {};
	
	conf.get = function (liJQ, params) {return null; };
	conf.set = function (liJQ, data, params) {};

	conf.before = function (paramsNames, paramsValues, paramsValuesActiveIndex) {};
	conf.after = function (paramsNames, paramsValues, paramsValuesActiveIndex) {};

	conf.fadeSpeed = 100;

    //
	var boxJQ = null;
	var listJQ = null;
	
	var lists = {};

	var paramsNames = [];
	var paramsValues = [];
	var paramsValuesActiveIndex = [];

	var listEntryCloneJQ = null;

	/**
	 * 
	 */
    var init = function (local_conf) {
		conf = jQuery.extend(conf, local_conf);

		//
		boxJQ = jQuery('#' + conf.boxId);
		listJQ = boxJQ.find('.list > ul');

		//
		for(var param in conf.params) {
			var i = paramsNames.length;
			
			paramsNames[i] = param;
			paramsValues[i] = conf.params[param];
			paramsValuesActiveIndex[i] = 0;
		}

		//
		for(var i = 0; i < paramsNames.length; i++) {
			for(var j = 0; j < paramsValues[i].length; j++) {
				boxJQ.find('.listFunctions .' + paramsNames[i] + ' .' + paramsValues[i][j])
					.each(function() {
						jQuery(this).addClass('param_' + i + '_' + j);
						
						if(jQuery(this).hasClass('active')) {
							paramsValuesActiveIndex[i] = j; 
						}
					})
					.click(function() {
						if(jQuery(this).hasClass('active')) {
							return true;
						}
						
						var paramsValuesIndex = paramsValuesActiveIndex.slice(); // clone
						var paramChange = tools.getClassData(this, 'param_', '').split('_');

						paramsValuesIndex[parseInt(paramChange[0])] = parseInt(paramChange[1]);
						
						showList(paramsValuesIndex);

						return false;
					});
			}
			
			//
			listEntryCloneJQ = listJQ.find('li').eq(0).clone();
		}
		
		//
		var paramsNamesValues = {};

		for(var i = 0; i < paramsNames.length; i++) {
			paramsNamesValues[paramsNames[i]] = paramsValues[i][paramsValuesActiveIndex[i]];
		}
		
		var list = [];

		listJQ.children('li').each(function(i) {			
			list[i] = conf.get(listJQ.children('li').eq(i), paramsNamesValues);
		});

		var slug = encodeSlug(paramsValuesActiveIndex);

		lists[slug] = paramsNamesValues;
		lists[slug].list = list;

        //
        init = function () {};
    };

    //
    var tools = {};

    /**
     * 
     * @param {Object} node
     * @param {String} prefix
     * @param {String} suffix
     */
    tools.getClassData = function (node, prefix, suffix) {
        prefix = ' ' + prefix;
        suffix = suffix + ' ';

        var c = ' ' + jQuery(node).attr('class') + ' ';
        var start = c.indexOf(prefix);
        var stop = c.indexOf(suffix, start + prefix.length);

        if (start === -1 || stop === -1) {
            return '';
        }

        return c.slice(start + prefix.length, stop);
    };

	/**
	 * 
	 */
	var encodeSlug = function(paramsValuesIndex) {
		var slug = 'i';
		
		for(var i = 0; i < paramsValuesIndex.length; i++) {
			slug += '_' + paramsValuesIndex[i];
		}
		
		return slug;
	}

	/**
	 * 
	 */
	var decodeSlug = function(slug) {
		var paramsValuesIndex = slug.substring(2, slug.length).split('_');
		
		for(var i = 0; i < paramsValuesIndex.length; i++) {
			paramsValuesIndex[i] = parseInt(paramsValuesIndex[i]);
		}
		
		return paramsValuesIndex;
	}

	/**
	 * 
	 */
	var showList = function (paramsValuesIndex) {
		listJQ.queue(function() {
			var paramsNamesValues = {};

			for(var i = 0; i < paramsNames.length; i++) {
				paramsNamesValues[paramsNames[i]] = paramsValues[i][paramsValuesActiveIndex[i]];
			}

			conf.before(paramsNamesValues);
			
			listJQ.dequeue();
		});

		var slug = encodeSlug(paramsValuesIndex);

		if(typeof(lists[slug]) === 'undefined') {
			loadList(paramsValuesIndex);
		}
		
		listJQ.fadeOut(conf.fadeSpeed);
		
		listJQ.queue(function() {
			var paramsNamesValues = {};

			for(var i = 0; i < paramsNames.length; i++) {
				paramsNamesValues[paramsNames[i]] = paramsValues[i][paramsValuesActiveIndex[i]];
			}

			listJQ.children('li').remove();

			if(typeof(lists[slug]) !== 'undefined') {
				for(var i = 0; i < lists[slug].list.length; i++) {
					var li = listEntryCloneJQ.clone();

					li
						.appendTo(listJQ)
						.removeClass('i1')
						.addClass('i' + (i + 1) + (i + 1 === lists[slug].list.length ? ' ilast' : ''));
				}
				
				listJQ.children('li').each(function(i) {
					if(typeof(lists[slug].list[i]) !== 'undefined') {
						conf.set(listJQ.children('li').eq(i), lists[slug].list[i], paramsNamesValues);
						jQuery(this).show();
					}
					else {
						jQuery(this).hide();
					}
				});
			}

			paramsValuesActiveIndex = paramsValuesIndex;

			for(var i = 0; i < paramsNames.length; i++) {
				paramsNamesValues[paramsNames[i]] = paramsValues[i][paramsValuesActiveIndex[i]];

				for(var j = 0; j < paramsValues[i].length; j++) {					
					boxJQ
						.find('.listFunctions .' + paramsNames[i] + ' .' + paramsValues[i][j])
							.removeClass('active')
							.each(function() {
								if(j === paramsValuesActiveIndex[i]) {
									jQuery(this).addClass('active');
								}
							});
				}
			}

			conf.after(paramsNamesValues);

			listJQ.dequeue();
		});

		listJQ.fadeIn(conf.fadeSpeed);
	};

	/**
	 * 
	 */
	var loadList = function (paramsValuesIndex) {
		listJQ.queue(function() {
			var url = conf.listAjaxUrl;

			for(var i = 0; i < paramsNames.length; i++) {
				url = url.replace('{' + paramsNames[i] + '}', paramsValues[i][paramsValuesIndex[i]]);
			}

            jQuery.ajax({
                type: 'GET',
                url: url,
                data: {inpl_network_request: 1},
                dataType: 'json',
                success: function (json, textStatus) {
					var paramsValuesIndex = [];
					
					for(var i = 0; i < paramsNames.length; i++) {
						for(var j = 0; j < paramsValues[i].length; j++) {
							if(paramsValues[i][j] === json[paramsNames[i]]) {
								paramsValuesIndex[i] = j;
							}
						}
					}

					lists[encodeSlug(paramsValuesIndex)] = json;

					listJQ.dequeue();
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
					listJQ.dequeue();
                }
			});
        });
	};

	//
    jQuery(document).ready(
        function () {
            init(local_conf);
        });
};
