/*global YAHOO*/
/*jslint white: true, browser: true, devel: true, windows: true, vars: false, undef: true, nomen: true, eqeq: false,
  plusplus: true, bitwise: true, regexp: true, newcap: true, sloppy: false */



YAHOO.namespace("is24.finden");

YAHOO.is24.finden.RegionAutoComplete = function (inputFieldId, listContainerId, geoCodeFieldId, submitButtonId, immoType, dataFilesRoot, geoCodeDefault, type, callBackOnSelectedItem, toShow, showStates) {
	"use strict";

	var dataSource,
		autoComplete,
		geoCodeField,
		inputField,
		submitButton,
		listContainer,
		lastInputFieldValue,
		maxQueryLength;

	function logError(exc) {
		if (typeof console !== 'undefined') {
			console.error("In the region autocompletet accurs an error - " + exc);
		}
	}	

	function encodeFileName(input) {
		var allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
			out = "",
			i;

		for (i = 0; i < input.length; i = i + 1) {
			if (allowedChars.indexOf(input.charAt(i)) !== -1) {
				out += input.charAt(i);
			} else {
				out += "_" + input.charCodeAt(i);
			}
		}

		return out;
	}

	function createQueryUrl(sQuery) {
		var urlParts = [];

		sQuery = decodeURIComponent(sQuery);
		sQuery = sQuery.toLowerCase();

		if (sQuery.length > 0) {
			urlParts[0] = encodeFileName(sQuery.substring(0, 1));
		}

		if (sQuery.length > 1) {
			urlParts[1] = encodeFileName(sQuery.substring(0, 2));
		}

		if (sQuery.length > maxQueryLength) {
			urlParts.push(encodeFileName(sQuery.substring(0, maxQueryLength)));
		} else {
			urlParts.push(encodeFileName(sQuery));
		}

		return urlParts.join("/") + "_.txt";
	}
	
	function ignoreNoneLettersAndNumbers(stringToTransform) {
		return stringToTransform.replace(/[^A-Za-z0-9]/g, " ");
	}

	function sortRegions(regions) {
		var equalRegions, i,
			filterdRegions,
			sQuery = inputField.value;

		if (sQuery.length > maxQueryLength) {
			equalRegions = [];
			filterdRegions = [];
			for (i = 0; i < regions.length; i = i + 1) {
				if (ignoreNoneLettersAndNumbers(regions[i][0].toLowerCase()) === ignoreNoneLettersAndNumbers(sQuery.toLowerCase())) {
					equalRegions.push(regions[i]);
				} else {
					if (ignoreNoneLettersAndNumbers(regions[i][0].toLowerCase()).indexOf(ignoreNoneLettersAndNumbers(sQuery.toLowerCase())) === 0) {
						filterdRegions.push(regions[i]);
					}
				}
			}
			regions = equalRegions.concat(filterdRegions);
		}
		
		return regions;
	}

	function filterRegions(regions, oResponse) {
		var i, tempRegions,
			filteredStates = 0,
			indexCounter = 0;

		if (!showStates) {
			tempRegions = regions;
			indexCounter = 0;
			regions = [];
			for (i = 0; i < tempRegions.length; i = i + 1) {

				// 7 because of the GEOCode, the states have only 7 signs, cities have more.
				if (tempRegions[i][1].toString().length > 7) {
					regions.push(tempRegions[i]);
					indexCounter = indexCounter + 1;
				} else {
					filteredStates = filteredStates + 1;
				}

				if (indexCounter === toShow) {
					break;
				}
			}
		} else {
			tempRegions = regions;
			indexCounter = 0;
			regions = [];
			for (i = 0; i < toShow && i < tempRegions.length; i = i + 1) {
				regions.push(tempRegions[i]);
			}
		}

		if (oResponse[immoType] && oResponse[immoType].count > toShow && (regions.length + filteredStates) >= toShow) {
			regions.push(["Alle Alternativen anzeigen", 0, 0]);
		}

		return regions;
	}

	function parseJSONData(oRequest, oResponse) {
		var regions = [];

		if (typeof oResponse !== "object") {
			logError("text response could not parsed into json");
		}

		if (oResponse[immoType] && oResponse[immoType].count > 0) {
			regions = oResponse[immoType].regions;
		}

		regions = sortRegions(regions);
		regions = filterRegions(regions, oResponse);

		return {"results": regions};
	}

	function formatResult(oResultData, sQuery, sResultMatch) {
		var out;

		if (oResultData[1] === 0) {
			out = "<div class=\"other\"><a href=\"#\">" + oResultData[0] + "</a></div>";
		} else {
			out = "<div class=\"region\">" + oResultData[0] + "</div>";

			if (oResultData[2] > 0) {
				out += "<div class=\"count\">" + oResultData[2] + "</div>";
			}
		}

		return out;
	}

	function attachEventListener() {
		autoComplete.doBeforeExpandContainer = function () {
			geoCodeField.value = "";
			lastInputFieldValue = inputField.value;
			return true;
		};

		autoComplete.itemSelectEvent.subscribe(function (item, data) {
			var region = data[2];
			if (region[1] === 0) {
				inputField.value = lastInputFieldValue;
				geoCodeField.value = -1;
				submitButton.click();
			} else {
				geoCodeField.value = region[1];
			}
			if (callBackOnSelectedItem) {
				callBackOnSelectedItem();
			}
		});

		autoComplete.unmatchedItemSelectEvent.subscribe(function (eventName, data) {
			var li;

			try {
				autoComplete = data[0];
				li = autoComplete.getListItems();
				if (li.length > 0 && autoComplete.isContainerOpen()) {
					geoCodeField.value = autoComplete.getListItemData(li[0])[1];
				} else {
					geoCodeField.value = "";
				}
			} catch (e) {
				geoCodeField.value = "";
			}
		});

		autoComplete.typeAheadEvent.subscribe(function (eventName, data) {
			var li;

			autoComplete = data[0];
			li = autoComplete.getListItems();
			geoCodeField.value = autoComplete.getListItemData(li[0])[1];
		});
	}

	function initDataSource() {
		dataSource = new YAHOO.util.XHRDataSource(dataFilesRoot);
		dataSource.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
		dataSource.parseJSONArgs = false;
		dataSource.connXhrMode = "ignoreStaleResponses"; //Send all requests, but handle only the response for the most recently sent request.
		dataSource.responseSchema = {resultsList: "results", fields: [0, 1, 2]};
		dataSource.parseJSONData = parseJSONData;
	}

	function initAutoComplete() {
		var moreRegionsLinkPlaceHolder = 1;
		
		autoComplete = new YAHOO.widget.AutoComplete(inputField, listContainer, dataSource);
		autoComplete.generateRequest = createQueryUrl;
		autoComplete.formatResult = formatResult;
		autoComplete.maxResultsDisplayed = toShow + moreRegionsLinkPlaceHolder;
	}

	function initDefaults() {
		if (typeof toShow === "undefined" || toShow > 20) {
			toShow = 10;
		}
		if (typeof showStates === "undefined") {
			showStates = true;
		}
		lastInputFieldValue = inputField.value;
		maxQueryLength = 5;
	}

	function initDomObjects() {
		inputField = document.getElementById(inputFieldId);
		geoCodeField = document.getElementById(geoCodeFieldId);
		submitButton = document.getElementById(submitButtonId);
		listContainer = document.getElementById(listContainerId);
	}

	function init() {
		initDomObjects();
		initDefaults();
		initDataSource();
		initAutoComplete();
	}

	init();
	attachEventListener();
};

