/**
 * Scripts to manage the customer box
 */

 var CustomerQuote = new Class({
 	
	initialize: function(options_base){
		// default values
		this.index = null;
		this.quote = "";
		this.logo = "";
		this.height = null;
		this.width = null;
		
		// get the values from the options
		var options = new Hash(options_base);
		
		if (options.has('index'))
			this.index = index;
		
		if (options.has('quote'))
			this.quote = options['quote'];
			
		if (options.has('logo'))
			this.logo = options['logo'];
			
		if (options.has('height'))
			this.height = options['height']
			
		if (options.has('width'))
			this.width = options['width']
	}
	
 });
 
 var CustomerBoxJS = new Class ({ 	
	Implements : [Chain, Events],
	
	initialize: function (customer_manager_url) {
		// save the url
		this.customer_manager_url = customer_manager_url;
		
		// time for the effects
		this.effectsTime = 1000;
		
		// time for get next quote
		this.nextTime = 10000;
		//this.nextTime = 5000;
		
		// get the html zones
		this.fullzone = $('customerbox-js-fullbox');
		this.customerboxzone = $('customerbox-js');
		this.quotezone = $('customerbox-js-quote');
		this.logozone = $('customerbox-js-logo');
		
		// hide box
		this.hideBox = new Element('div');
		this.hideBox.setStyle('background-color','white');
		this.hideBox.setStyle('position', 'absolute');
		this.hideBox.setStyle('display', 'none');
		var body = $$('body')[0];
		this.hideBox.inject(body);
		 
		// variables
		this.cached = new Hash();
		this.showed = new Hash();
		this.totalLen = null;
		
		// flags
		this.stateok = true;
		this.jsonRunning = false;
		this.effectRunning = false;
		
		// initialize the engine if zones are all right
		if (this.customerboxzone == null) {
			return;
		}
		
		if (this.quotezone == null) {
			return;
		}
		
		if (this.logozone == null) {
			return;
		}
		
		this.start();
	},
	
	start: function() {
		// flag
		this.jsonRunning = true;
		
		// get the length
		var jsonRequest = new Request.JSON({url: this.customer_manager_url, method: "post", async: false, urlEncoded: false});
		
		// set the encoding
		jsonRequest.setHeader("Content-Type","application/json-rpc; charset=UTF-8");
		
		// events
		jsonRequest.addEvent('success',this.getLengthSuccess.bind(this));
		jsonRequest.addEvent('failure',this.getLengthFailure.bind(this));
		jsonRequest.addEvent('exception',this.getLengthFailure.bind(this));
		jsonRequest.addEvent('cancel',this.getLengthFailure.bind(this));
		
		// data
		var data = {id: "customerbox-getlength", 'method': "getCustomerLen", 'params': []};
		var jsondata = JSON.encode(data);
		
		// send
		jsonRequest.send(jsondata);
	},
	
	////////////////////////////////////////////////// GET LENGTH

	getLengthSuccess: function (text, xml) {
		// flag
		this.jsonRunning = false;
		
		// get the data
		var jsonresult = JSON.decode(xml);
		
		// if it's not successful
		if (jsonresult['error'] != null)
			return this.getLengthFailure();
			
		// save (if it's less than 1, error)
		this.totalLen = jsonresult['result'];
		
		if (this.totalLen < 1)
			return this.getLengthFailure();
		
		// set the timer for the random quote
		this.getRandomQuote();
		this.getRandomQuote.periodical(this.nextTime, this);
	},
	
	getLengthFailure: function () {
		// flag
		this.jsonRunning = false;
		
		this.stateok = false;
	},
	
	///////////////////////////////////////////////////////////// GET RANDOM QUOTE
	getRandomQuote: function() {
		// if we are running, cancel this
		if (this.jsonRunning || this.effectRunning) {
			return;
		}
		
		// get random number
		if (this.showed.getLength() == this.totalLen) {
			this.showed = new Hash();
		}
	
		var seed = seed = Math.random();
		var quote = Math.round(seed * (this.totalLen - 1)); 
		var goodNumber = false;
		var maximum = this.totalLen;
		
		// search for one not showed
		while ((!goodNumber) && (maximum>0)) {
			if (!this.showed.has(quote)) {
				goodNumber = true;
				this.showed[quote] = true;
				break;
			}
			
			quote += 1;
			if (quote >= this.totalLen)
				quote = 0;
				
			maximum -= 1;
		}
		
		// initialize quote obj
		var quoteObj = null;
		
		// check if we have cached the quote
		if (!this.cached.has(quote)) {
			quoteObj = this.getRemoteQuote(quote);
		}
		
		if (!this.cached.has(quote)) {
			return;
		}
		
		// change quote
		this.changeQuote(quote);
	},
	
	/////////////////////////////////// OBTAIN QUOTE
	
	getRemoteQuote: function(index) {
		// flags
		this.jsonRunning = true;
		
		// json request
		var jsonRequest = new Request.JSON({url: this.customer_manager_url, method: "post", async: false, urlEncoded: false});
		
		// set the encoding
		jsonRequest.setHeader("Content-Type","application/json-rpc; charset=UTF-8");
		
		// events
		var info = new Hash();
		info['object'] = this;
		info['index'] = index;
		jsonRequest.addEvent('success',this.getQuoteSuccess.bind(info));
		jsonRequest.addEvent('failure',this.getQuoteFailure.bind(this));
		jsonRequest.addEvent('exception',this.getQuoteFailure.bind(this));
		jsonRequest.addEvent('cancel',this.getQuoteFailure.bind(this));
		
		// data
		var data = {id: "customerbox-getlength", 'method': "getCustomer", 'params': [index]};
		var jsondata = JSON.encode(data);
		
		// send
		jsonRequest.send(jsondata);
	},
	
	getQuoteSuccess: function (text, xml) {
		// elements
		object = this['object'];
		index = this['index'];
		
		// flag
		object.jsonRunning = false;
		
		// get the data
		var jsonresult = JSON.decode(xml);
		
		// if there is failures
		if (!jsonresult['error'] == null)
			return object.getQuoteFailure();
			
		// save
		var data = jsonresult['result'];
		var newQuote = new CustomerQuote(data);
		newQuote.index = index;
		
		// cache
		object.cached[index] = newQuote;
		
		// return
		return newQuote;
	},
	
	getQuoteFailure: function() {
		// flag
		this.jsonRunning = false;
		
		this.stateok = false;
	},
	
	///////////////////////////////////////////// CHANGE QUOTE
	
	locateHideBox: function () {
		var quoteposition = this.quotezone.getPosition();
		var quotesize = this.quotezone.getSize();
		var logoposition = this.logozone.getPosition();
		var logosize = this.logozone.getSize();
		
		var x = quoteposition.x;
		
		if (logoposition.x < x)
			x = logoposition.x;
			
		var y = quoteposition.y;
		
		var width = quoteposition.x - x + quotesize.x;
		var altwidth = logoposition.x - x + logosize.x;
		
		if (altwidth > width)
			width = altwidth;
			
		var height = (logoposition.y - y) + logosize.y;
		
		this.hideBox.setStyle('top',y-1);
		this.hideBox.setStyle('left', x-1);
		this.hideBox.setStyle('height', height+2);
		this.hideBox.setStyle('width', width+2);
		
		/*var position = this.fullzone.getPosition();
		var dimension = this.fullzone.getSize();
		this.hideBox.setStyle('top',position.y+1);
		this.hideBox.setStyle('left', position.x);
		this.hideBox.setStyle('height', dimension.y-1);
		this.hideBox.setStyle('width', dimension.x);*/
	},
	
	changeQuote: function (index) {
		// get the new quote
		if (!this.cached.has(index)) {
			this.stateok = false;
			return;
		}
		
		// flags
		this.effectRunning = true;
		
		var newQuote = this.cached[index];
		
		// put the hide box		
		this.locateHideBox();
		this.hideBox.setStyle('opacity', 0);
		this.hideBox.setStyle('display', 'block');
		
		var dissapearEffect = new Fx.Tween(this.hideBox, {
			property: 'opacity',
			transition: Fx.Transitions.Expo.easyIn,
			duration: this.effectsTime});
		
		var middleStep = function(){
			// remove
			this.quotezone.empty();
			this.logozone.empty();
			
			// hide
			this.customerboxzone.setStyle('opacity',0);
			
			// put
			var quote = "\"" + newQuote.quote + "\"";
			this.quotezone.appendText(quote);
			
			var image = new Element("img");
			image.setProperty("src", newQuote.logo);
			
			if (newQuote.height != null) 
				image.setProperty("height", newQuote.height);
			
			if (newQuote.width != null) 
				image.setProperty("width", newQuote.width);
			
			image.inject(this.logozone);
			
			// Move the hide box
			this.locateHideBox();
			this.customerboxzone.setStyle('opacity',1);
			
			// appear
			var apearEffect = new Fx.Tween(this.hideBox, {
				property: 'opacity',
				transition: Fx.Transitions.Expo.easyIn,
				duration: this.effectsTime
			});
			
			var end = function(){
				// quit hide box
				this.hideBox.setStyle('display', 'none');
				
				// flags
				this.effectRunning = false;
			};
			
			apearEffect.addEvent('complete', end.bind(this));
			apearEffect.start(0);
		};
		
		dissapearEffect.addEvent('complete', middleStep.bind(this));
		dissapearEffect.start(1);
	}	
});

