
(function( $, undefined ) {
$.widget( "ui.vpscontrol", {
	options: {
		members: {}
		,elements : {}
		,evalues: {}
		,lowthreshold: 0
		,curmember: 1
		,memberpos: {}
	}

	,_create: function() 
	{
		this.parse_members();
	}
	,destroy: function() { $.Widget.prototype.destroy.apply( this, arguments); }
	,get: function(val) { return this.option(val); }
	,set: function(key, val) { this.option(key,val); }
	,returnlen: function( a )
	{
		if (typeof(a.length) != 'undefined' && typeof(a.length) == 'function') {
			return a.length;
		}
		if (typeof(a) != 'object') return 0;
		var c=0;
		for (var i in a ) {
			if ( typeof(a[i]) == 'function') continue;
			c++;
		}
		return c;
	}
	,roundNumber: function (num, dec) {
		var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
		return result.toFixed(2);
	}
	,parse_members: function()
	{
		var c = this.element.children();
		if (c.length == 0)
		{
			this.element.html('ERROR vpscontrol: no children found');
			return;
		}
		
		var m = {};
		c.each(function(){
			var o = $.parseJSON($(this).attr('data-config'));
			m[o.VPS] = o;
		});		
		this.set("members",m);
	}
	/*
		registers elements representing, ram, hdd , traffic
		on threshold check values of the controllerobject
	*/
	,register_element: function (key, jq_object)
	{
		var e = this.get('elements');
		if (typeof(e[key]) == 'undefined') {
			e[key] = jq_object;
		}
	}
	,getvps: function (idx, val )
	{
		var m = this.get('members');
		var ri = 0;
		for (var i in m )
		{
			for (var y in m[i]) {
				if (typeof(m[i][idx]) !== 'undefined') {
					if (m[i][idx] <= val ) ri = i;
				}
			}
		}
		return m[ri];
	}
	/*
		check if one of the members tripped a thresholdvalue
		, if so , check all others
	*/	
	,initmembers: function()
	{
		this.checkmember('RAM');
	}
	,checkmember: function ( key, val)
	{
		var e = this.get("elements");
		var m = this.get("members");
		var cur = this.get('curmember');
		var stick = this.get('sticky_elements');
		var sloose = this.get('sticky_loose');
		
		var curvps = m[cur];

		// first init is without value
		if (typeof(val) == 'undefined') val = curvps[key];		
		var vps = this.getvps(key,val);	// get package on current member, value
		var pos = this.get('memberpos'); // vpsnr per element selection
		
		// ... so init all vpsses and trigger first recalibration
		var init = 0;
		if (this.returnlen(pos) == 0) {
			init = 1;
			for(var i in e) {
				if (typeof(pos[i]) == 'undefined') {
					this.recalibrate_slider(i,curvps[i]);
					pos[i] = curvps.VPS;
				}
			}
		}
		
		//check if memeber who calls, triggers VPS treshold value
		// and set the member->package table
		if (vps.VPS != pos[key]) { pos[key] = vps.VPS; }

		// it doesn't matter if the caller triggers a VPS threshold value
		// we are looking for the lowest vps.VPS in all the slides
		// to determin the current vps package we are in
		//
		// get lowsest VPS number in positiontable
		var h = 0; // < holds the lowest vps Package NR
		for( var i in pos )
		{
			if(stick[i]) continue; // skip is memeber is in sticky array
			h = h == 0 ? pos[i] : (pos[i] >= h ? h : pos[i]);
		}
		
		// set sticky elements
		// so we can recalibrate all members and get the right price
		for( var i in stick ) {
			if (typeof(sloose[i]) != "undefined" && h >= sloose[i]) {
				pos[i] = h; continue;
			}
		
			sv = parseInt(this.getmembervalues(i).value);
			svps = this.getvps(i, sv);
			// if we are pulling the member
			if (key == i && (svps.VPS <= h || sv < parseInt(stick[i]))) { 
				if (pos[i] <= h) h = svps.VPS; 
			}
			
			if (key != i && typeof(stick[i]) != 'undefined') {
				if (typeof(sloose[i]) != "undefined" && h >= sloose[i]) {
					//nothing
				}
				else this.setslider(i, h);
			}				
			stick[i] = sv
			pos[i] = h;
		}		


		// if VPS package changes, reset vps.radiobut
		if (  h !== cur) {
			$('input[name=vps]:radio').each(function(){
				$(this).attr('checked',false);
				if ( $(this).attr('value') == h ) $(this).attr('checked', true);
			});
		}		


		this.set('memberpos',pos);
		this.set('curmember',h);

		// now recalibrate all sliders (if necessary)
		// and display prices
		
		var d = this.get('display');
		var tprice = m[h].PRICE;
		
		$(d.VPSID).html(h);
		$(d.PRICE).html(m[h].PRICE);

		//preparse cores
		this.recalibrate_slider('RAM',m[h]['RAM']);
		var rama = this.getmembervalues('RAM',m[h]['RAM']);
		var cores = this.checkCores( rama.value );
		this.slider_lowerpos('CPUCORES',cores);
		
		// we need memdata in this object for 
		// further cpu calculations
		var memval = {}; 
		
		// actual loop and price display
		for (var i in e ) {
			if (i == 'RAM') var a = rama;
			else {
				// recalculate based on VPS			
				if (init == 0 && h !== cur) {
					this.recalibrate_slider(i,m[h][i]);
				}			
				var a = this.getmembervalues(i,m[h][i]);	
			}

			memval[i] = a;						


			var disp = a.value - m[h][i];
			if (disp < 0 ) disp = 0;

			tprice += a.price;
			$(d[i]).html( disp );			
		}
		
		this.set('memval',memval);		
		$(d.TPRICE).html( this.roundNumber(tprice,2)  );

		//check cores and ram
		if (key != 'CPUCORES') {
			if ( m[h]['CPUCORES'] != cores ) {
				m[h]['CPUCORES'] = cores;
				this.forceslider('CPUCORES',cores);
			}			
		} 
		else if (memval['CPUCORES'].value > cores ){
			this.fillcores( memval['CPUCORES'].value );
		}
		

	}
	,setsliders: function (vpsnr)
	{
		var e = this.get("elements");
		var w = this.get('element_widget');
		var m = this.get("members");
		
		// refactor, this will call checkmembers for each member
		
		for( var i in e ) {		
			if (i == 'CPUCORES'){
				var mv = this.get('memval');
				var c = this.checkCores( mv['RAM'].value );
				m[vpsnr][i] = c;
			}
			eval('$("'+e[i]+'").'+w+'("setslider", "'+m[vpsnr][i]+'")');
		}
	}
	,setslider: function (kind , vpsnr)
	{
		var e = this.get("elements");
		var w = this.get('element_widget');
		var m = this.get("members");
		eval('$("'+e[kind]+'").'+w+'("setslider", "'+m[vpsnr][kind]+'")');
	}	
	,forceslider: function (kind , am)
	{
		var e = this.get("elements");
		var w = this.get('element_widget');
		eval('$("'+e[kind]+'").'+w+'("setslider", "'+am+'")');
	}
	,slider_lowerpos: function (kind , am)
	{
		var e = this.get("elements");
		var w = this.get('element_widget');
		eval('$("'+e[kind]+'").'+w+'("setlowerpos", "'+am+'")');
	}	
	,recalibrate_slider: function(key , val)
	{
		var e = this.get("elements");
		var w = this.get('element_widget');
		return eval('$("'+e[key]+'").'+w+'("recalibrate", "'+val+'")');
	}
	,getmembervalues: function(key, val)
	{
		var e = this.get("elements");
		var w = this.get('element_widget');
		return eval('$("'+e[key]+'").'+w+'("return_values")');
	}
	/*
		one of the members crossed a boundry, check 
		what the lowesr VPSnr is and recalibrate for the best
		price
	*/
	,threshold: function( key, val )
	{
		// check if called item::amount is bigger
		// than current
		var cur = this.get('curmember');
		var vps = this.getvps(key,val);
		var e = this.get("elements");
		var w = this.get('element_widget');

		if (cur !=0 && cur <= vps.VPS) {
			// get the current prices from member without recalibrating
			return eval('$("'+e[key]+'").'+w+'("return_values")');
		}
		this.set('curmember',vps.VPS);
		return eval('$("'+e[key]+'").'+w+'("return_values", true)');
	}
	,checkCores: function( ram )
	{
		if (typeof(ram) == undefined) return;
		/*
		for (var i = 1; i < 6; i++) {
			$('#cores'+i).css({'background-color':'#d2d4d9'});
		}
		*/
		var c = 0;
		if (ram < 1024 ) c = 1;
		if (ram >= 1024 && ram < 4096 ) c = 2;
		if (ram >= 4096 && ram < 8192) c = 3;
		if (ram >= 8192 ) c = 4;
		this.fillcores(c);
		return c;
		
	}
	,fillcores: function ( n )
	{
		/*
		for (var i = 1; i < 6; i++) {
			if (i <= n ) $('#cores'+i).css({'background-color':'#fc9d44'});
			else $('#cores'+i).css({'background-color':'#d2d4d9'});
		}
		*/
		$('#coreghz').html((Math.round(n * 220)/100)+' GHz');

		this.recalibrate_slider('CPUCORES' , n);
		//this.forceslider('CPUCORES' , n);
		//var d = this.get('display');
	}
	/*
		get all values for submittance
	*/
	,getvalues: function()
	{
		var m = this.get("members");
		var cur = this.get('curmember');
		var curvps = m[cur];

		r = {};
		for( var i in curvps)
		{
			if (i == 'PRICE') continue;
			if (i == 'VPS') { r[i] = curvps[i]; continue; }
			r[i] = this.getmembervalues(i).value;
		}
		return r;
	}	

});

$.extend( $.ui.vpscontrol, {
	version: "@VERSION"
});

})( jQuery );



