var StopReportsController = function(requestUrl, requestTimeout) {

	var E_CONTROLSLOADING = "stopreports_controlsLoading";
	var E_CONTROLSTIMEOUT = "stopreports_controlsTimeout";
	var E_CONTROLSBLOCK = "stopreports_controlsBlock";
	var E_RESULTSLOADING = "stopreports_resultsLoading";
	var E_RESULTSTIMEOUT = "stopreports_resultsTimeout";
	var E_RESULTSERROR = "stopreports_resultsError";
	var E_RESULTSBLOCK = "stopreports_resultsBlock";

	var E_RF_TITLE = "stopreports_resultsBlock_title";
	var E_RF_DATEVIEW = "stopreports_resultsBlock_date";
	var E_RF_GLPERCENT = "stopreports_resultsBlock_glPercent";
	var E_RF_GLPERCENT1 = "stopreports_resultsBlock_glPercent1";
	var E_RF_SIGNALSCOUNT = "stopreports_resultsBlock_signalsCount";

	var C_ROW = "";
	var C_ROWACTIVE = "active";
	var C_FIELD = "field";
	var C_FIELDGAIN = "field_gain";
	var C_FIELDLOSS = "field_loss";

	this.pDay = new StopReportsPeriod("stopreports_rowDay", "stopreports_listDay", "d", "days", "Daily");
	this.pWeek = new StopReportsPeriod("stopreports_rowWeek", "stopreports_listWeek", "w", "weeks", "Weekly");
	this.pMonth = new StopReportsPeriod("stopreports_rowMonth", "stopreports_listMonth", "m", "months", "Monthly");
	this.pYear = new StopReportsPeriod("stopreports_rowYear", "stopreports_listYear", "y", "years", "Yearly");

	this.inited = false;
	this.lastPeriod = null;
	this.lastDate = null;

	this.periods = [this.pDay, this.pWeek, this.pMonth, this.pYear];

	this.init = function() {
		this.refreshControls();
	}

	this.refreshControls = function() {
		hideElement(E_CONTROLSTIMEOUT);
		hideElement(E_CONTROLSBLOCK);
		showElement(E_CONTROLSLOADING);
		this.loadLists();
	}

	this.loadLists = function() {
		var request = ((typeof XMLHttpRequest != 'undefined') ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
		var url = requestUrl + "?action=list&period=" + this.getPeriodsRequestNames() + "&requestId=" + (new Date().getTime());
		request.open("GET", url, true);
		var thisClosure = this;
		request.onreadystatechange = function() {
			if (request.readyState == 4) {
				if (request.status == 200)
					thisClosure.processListsResponse(request.responseText);
			}
		}
		request.send(null);
		setTimeout((function() {thisClosure.processListsTimeout(request)}), requestTimeout);
	}

	this.getPeriodsRequestNames = function() {
		var result = "";
		for (var i = 0; i < this.periods.length; i++)
			result += this.periods[i].getRequestName();
		return result;
	}

	this.processListsResponse = function(responseText) {
		try {
			var response = eval("[" + responseText + "]")[0];
			for (var i in response) {
				for (var j in this.periods) {
					if (i == this.periods[j].getJsonName()) {
						this.populateList(this.periods[j], response[i]);
						break;
					}
				}
			}
		} catch (ignore) {}
		hideElement(E_CONTROLSLOADING);
		showElement(E_CONTROLSBLOCK);
		if (!this.inited) {
			this.inited = true;
			this.getYearReport(-1);
		}
	}

	this.populateList = function(period, values) {
		var listElement = getElement(period.getEList());
		listElement.options.length = 1;
		var j = 1;
		for (var i in values)
			listElement.options[j++] = new Option(values[i], i);
	}

	this.processListsTimeout = function(request) {
		if (request.readyState == 4 && request.status == 200)
			return;
		request.abort();
		hideElement(E_CONTROLSLOADING);
		showElement(E_CONTROLSTIMEOUT);
	}

	this.getDayReport = function(date) {this.getReport(this.pDay, date);}

	this.getWeekReport = function(date) {this.getReport(this.pWeek, date);}

	this.getMonthReport = function(date) {this.getReport(this.pMonth, date);}

	this.getYearReport = function(date) {this.getReport(this.pYear, date);}

	this.getReport = function(period, date) {
		if (date == 0)
			return;
		if (date == -1) {
			var list = getElement(period.getEList());
			if (list.options.length < 2)
				return;
			date = list.options[1].value;
			list.selectedIndex = 1;
		}
		this.resetSelectedPeriods(period);
		this.highlightPeriodRow(null);
		hideElement(E_RESULTSLOADING);
		hideElement(E_RESULTSTIMEOUT);
		hideElement(E_RESULTSERROR);
		hideElement(E_RESULTSBLOCK);
		showElement(E_RESULTSLOADING);
		this.loadReport(period, date);
	}

	this.resetSelectedPeriods = function(period) {
		for (var i in this.periods) {
			if (period.getEList() == this.periods[i].getEList())
				continue;
			getElement(this.periods[i].getEList()).selectedIndex = 0;
		}
	}

	this.refreshResults = function() {
		if (this.lastPeriod == null || this.lastDate == null)
			return;
		this.getReport(this.lastPeriod, this.lastDate);
	}

	this.loadReport = function(period, date) {
		var request = ((typeof XMLHttpRequest != 'undefined') ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
		var url = requestUrl + "?action=report&period=" + period.getRequestName() + "&date=" + date + "&requestId=" + (new Date().getTime());
		request.open("GET", url, true);
		var thisClosure = this;
		request.onreadystatechange = function() {
			if (request.readyState == 4) {
				if (request.status == 200)
					thisClosure.processReportResponse(period, request.responseText);
			}
		}
		request.send(null);
		setTimeout((function() {thisClosure.processReportTimeout(request, period, date)}), requestTimeout);
	}

	this.processReportResponse = function(period, responseText) {
		hideElement(E_RESULTSLOADING);
		if (responseText == "null") {
			showElement(E_RESULTSERROR);
			return;
		}
		try {
			var response = eval("[" + responseText + "]")[0];
			var report = new Report(response);
			this.highlightPeriodRow(period);
			this.showResults(period, report);
		} catch(e) {
			showElement(E_RESULTSERROR);
		}
	}

	this.processReportTimeout = function(request, period, date) {
		if (request.readyState == 4 && request.status == 200)
			return;
		request.abort();
		this.lastPeriod = period;
		this.lastDate = date;
		hideElement(E_RESULTSLOADING);
		showElement(E_RESULTSTIMEOUT);
	}

	this.highlightPeriodRow = function(period) {
		for (var i  in this.periods)
			setElementClassName(this.periods[i].getERow(), C_ROW);
		if (period != null)
			setElementClassName(period.getERow(), C_ROWACTIVE);
	}

	this.showResults = function(period, report) {
		var glPercentClass = C_FIELD;
		if (report.getGlPercent() > 0)
			glPercentClass = C_FIELDGAIN;
		else if (report.getGlPercent() < 0)
			glPercentClass = C_FIELDLOSS;
		var glPercent1Class = C_FIELD;
		if (report.getGlPercent1() > 0)
			glPercent1Class = C_FIELDGAIN;
		else if (report.getGlPercent1() < 0)
			glPercent1Class = C_FIELDLOSS;
		setElementContent(E_RF_TITLE, period.getAdjective());
		setElementContent(E_RF_DATEVIEW, report.getDateView());
		setElementContent(E_RF_GLPERCENT, report.getGlPercent() + " %");
		setElementClassName(E_RF_GLPERCENT, glPercentClass);
		setElementContent(E_RF_GLPERCENT1, report.getGlPercent1() + " %");
		setElementClassName(E_RF_GLPERCENT1, glPercent1Class);
		setElementContent(E_RF_SIGNALSCOUNT, report.getSignalsCount());
		showElement(E_RESULTSBLOCK);
	}
}

var StopReportsPeriod = function(eRow, eList, requestName, jsonName, adjective) {

	this.getERow = function() {return eRow;}

	this.getEList = function() {return eList;}

	this.getRequestName = function() {return requestName;}

	this.getJsonName = function() {return jsonName;}

	this.getAdjective = function() {
		return adjective;
	}
}

var Report = function(hash) {

	this.getPeriod = function() {return hash["period"];}

	this.getStartDate = function() {return hash["startDate"];}

	this.getDateView = function() {return hash["dateView"];}

	this.getGlPercent = function() {return hash["glPercent"];}

	this.getGlPercent1 = function() {return hash["glPercent1"];}

	this.getSignalsCount = function() {return hash["signalsCount"];}

	this.isCurrent = function() {return hash["isCurrent"];}
}