function Rate(rateName, rateLink)
{
	this._rateName = rateName;
	this._rateLink = rateLink;
	
	this._generateLink = function(link)
	{
		var newLink = document.createElement("a");
		newLink.setAttribute("href", link);
		newLink.innerHTML = this._rateName;
		
		return newLink;
	}
	
	this.getLink = function()
	{
		return this._generateLink(this._rateLink);
	}
}

function CalculatorModel()
{
	this._resultTraffic = 0;
	this._pointModels = new Array();
	this._listeners = new Array();
	
	this.addListener = function(listener)
	{
		this._listeners[this._listeners.length] = listener;
	}
	
	this.notifyListeners = function()
	{
		for (var index = 0; index < this._listeners.length; index++)
		{
			this._listeners[index].update();
		} 
	}
	
	this.update = function()
	{
		var resultTraffic = 0;
	
		for (var index = 0; index < this._pointModels.length; index++)
		{
			var pointModel = this._pointModels[index];
			resultTraffic += pointModel.getFinalValue();			
		}
		
		this._resultTraffic = resultTraffic;
		this.notifyListeners();
	}
	
	this.addPointModel = function(model)
	{
		this._pointModels.push(model);
	}
	
	this.getResultTraffic = function()
	{
		return this._resultTraffic;
	}
}

function CalculatorView(field, model)
{
	this._field = field;
	this._model = model;
	
	this._clearLinks = function()
	{
		while (this._getLinksContainer().lastChild)
		{
			this._getLinksContainer().removeChild(this._getLinksContainer().lastChild);
		}
	}
	
	this._addLink = function(rate)
	{
		this._getLinksContainer().appendChild(rate.getLink());
	}
	
	this._getLinksContainer = function()
	{
		return document.getElementById("links");
	}
	
	this._addDelimeter = function()
	{
		this._getLinksContainer().appendChild(document.createTextNode(", "));
	}
	
	this.update = function()
	{
		this._clearLinks();
	
		var resultTraffic = this._model.getResultTraffic();
		
		if (resultTraffic < 1) 
		{
			this._addLink(ratesArray[0]);
			this._addDelimeter();
			this._addLink(ratesArray[1]);
		}
		
		if (resultTraffic >= 1 && resultTraffic < 2) 
		{
			this._addLink(ratesArray[0]);
			this._addDelimeter();
			this._addLink(ratesArray[1]);
			this._addDelimeter();
			this._addLink(ratesArray[2]);
		}
		if (resultTraffic >= 2 && resultTraffic < 10) 
		{
			this._addLink(ratesArray[2]);
			this._addDelimeter();
			this._addLink(ratesArray[1]);
			this._addDelimeter();
			this._addLink(ratesArray[3]);
		}
		if (resultTraffic >= 10) 
		{
			this._addLink(ratesArray[2]);
			this._addDelimeter();
			this._addLink(ratesArray[3]);
		}

		this._field.setText(Math.round(resultTraffic * 10) / 10);
	}
}

function PointModel()
{
	this._value = 0;
	this._listeners = new Array();

	this.getFinalValue = function()
	{
		return this._value * this._coefficient;
	}

	this.setCoefficient = function(coefficient)
	{
		this._coefficient = coefficient;
	}
	
	this.setValue = function(value)
	{
		if (this._value != value)
		{
			this._value = value;
			this.notifyListeners();
		}
	}
	
	this.getValue = function()
	{
		return this._value;
	}

	this.addListener = function(listener)
	{
		this._listeners[this._listeners.length] = listener;
	}
	
	this.notifyListeners = function()
	{
		for (var index = 0; index < this._listeners.length; index++)
		{
			this._listeners[index].update();
		} 
	}
}

function PointView(field, model)
{
	this._field = field;
	this._model = model;
	
	this.update = function()
	{
		this._field.setValue(this._model.getValue());
	}
}

function PointController(Model)
{
	this._model = Model;
	
	this.setValue = function(newValue)
	{
		this._model.setValue(newValue);
	}
}

function initializePoint(sliderPrefix, maximumValue, coefficient, calculatorModel)
{
	// Adding field to store ext-field which display slider value
	Ext.Slider.prototype.pointController;

	var slider = new Ext.Slider(
		{
			renderTo: sliderPrefix + '-slider',
			minValue: 0,
			maxValue: maximumValue
		}
	);

	var field = new Ext.form.Field(
		{
			renderTo: sliderPrefix + '-field',
			readOnly: true,
			value: 0
		}
	);
	
	
	var model = new PointModel();
	model.setCoefficient(coefficient);
	var view = new PointView(field, model);
	model.addListener(view);
	
	calculatorModel.addPointModel(model);
	
	model.addListener(calculatorModel);
	
	slider.pointController = new PointController(model);
	slider.addListener(
		"change",
		function(slider)
		{
			slider.pointController.setValue(slider.getValue());
		}
	);
}

Ext.onReady(
	function()
	{
		ratesArray = new Array(4);

		ratesArray[0] = new Rate("HSDPA", "http://www.broadbanddeals.co.za/index.php?mode=cat&id=HSDPA");
		ratesArray[1] = new Rate("iBurst", "http://www.broadbanddeals.co.za/index.php?mode=cat&id=iBurst");
		ratesArray[2] = new Rate("ADSL", "http://www.broadbanddeals.co.za/index.php?mode=cat&id=ADSL");
		ratesArray[3] = new Rate("Neotel_NeoConnect", "http://www.broadbanddeals.co.za/index.php?mode=cat&id=Neotel");

		var calculatorModel = new CalculatorModel();
		
		Ext.form.Label.prototype.calculatorModel;
		var label = new Ext.form.Label(
			{
				renderTo: 'result',
				text: 0
			}
		);

		var calculatorView = new CalculatorView(label, calculatorModel);
		calculatorModel.addListener(calculatorView);
		
		initializePoint("surf", 50, 0.01 * 13 / 3, calculatorModel);
		initializePoint("email", 300, 0.000025 * 13 / 3, calculatorModel);
		initializePoint("email-attach", 300, 0.000244 * 13 / 3, calculatorModel);
		initializePoint("email-photo", 150, 0.0001 * 13 / 3, calculatorModel);
		initializePoint("music", 150, 0.004 * 13 / 3, calculatorModel);
		initializePoint("video", 150, 0.108 * 13 / 3, calculatorModel);
		initializePoint("movie", 40, 0.78125, calculatorModel);
		initializePoint("radio", 40, 0.023 * 13 / 3, calculatorModel);
		initializePoint("game", 60, 0.09 * 13 / 3, calculatorModel);
		initializePoint("skype", 20, 0.10986328125 * 13 / 3, calculatorModel);
		
		calculatorModel.update();
	}
);
