var Contacts = new Class({
	Implements: [Events, Options],
	
	options : {
		'id' 			: 'esl-contacts',
		'lang' 			: 'fr_CH',
		'data' 			: '/xml/towns.php',
		'server'		: 'eslagency',
		'display'		: 'fullsimple',		//fullsimple (contact), fulldetailed (demande rdv), fullslide (eslcompany), listsimple (QQPrint), office (contact), newsletter (newsletters footer)
		'office'		: null,
		'mergeCountries': true,
		'list'			: 'filtered',		// filtered or complete – display all offices (from server) or only offices with same lang
		'links'			: true,
		'showhead'		: false,
		
		onComplete		: $empty
	},
	
	initialize : function(options){
		this.setOptions(options);
		
		this.convertISOLang();
		
		this.officesList = new Hash();
		this.officesListExtra = new Hash();
		this.active = false;
		this.currentSpan = false;
		
		this.id = "esl-contacts_" + Math.floor(Math.random()*100000);
		document.write('<div id='+this.id+'></div>');
		
		this.loadJSON();
	},
	
	toElement : function(){
		return this.element;
	},
	
	createInterfaceList : function(){
		this.element = new Element('div', {
			'id' : this.options.id
		});
		this.list = new Element('ul', {'id' : 'list'}).inject(this.element);
		this.detail = new Element('div', {'id' : 'detail'}).inject(this.element);
	},
	
	loadJSON : function(){
		new Request.JSON({
			url : this.options.data,
			onSuccess : function(json, txt){
				switch(this.options.display) {
					case 'fullsimple' :
						this.parseJSONList(json, false);
						break;
					case 'fulldetailed' :
						this.parseJSONList(json, true);
						break;
					case 'fullslide' :
						this.parseJSONListSlide(json);
						break;
					case 'listsimple' : 
						this.parseJSONListSimple(json);
						break;
					case 'office' :
						this.parseJSONOffice(json);
						break;
					case 'newsletter' :
						this.parseJSONNewsletter(json);
						break;
					case 'landing' :
						this.parseJSONLanding(json);
						break;
				}
			}.bind(this)
		}).send();
	},
	
	getOfficeFullDetails : function(office){
		//we make the element
		var officeElement = new Element('div', {id : 'esl-office'});
		
		//address
		if(this.options.showhead && office.address.head) {
			if ($type(office.address.head) == 'string') office.address.head = [office.address.head];
			office.address.head.each(function(line){
				new Element('span', {html : this.getValue(line), 'class': 'head'}).inject(officeElement);
			}, this);
		}
		office.address.line.each(function(line){
			new Element('span', {html : this.getValue(line)}).inject(officeElement);
		}, this);
		if(office.address.more) {
			if ($type(office.address.more) == 'string') office.address.more = [office.address.more];
			office.address.more.each(function(line){
				new Element('span', {html : this.getValue(line)}).inject(officeElement);
			}, this);
		}
		
		//helpline
		if(office.helpline && (this.options.server == 'eslagency' || this.options.server == 'eslclub50')) {
			var hl = new Element('span', {html : this.getValue(office.helpline), 'class':'helpline'}).inject(officeElement);
			new Element('span', {html : officeDetails.helpline}).inject(hl, 'top');
		}
		
		//coordinates
		new Element('strong', {html : officeDetails.coordinates}).inject(officeElement);
		$H(office.contact).each(function(line, key){
			if(key == "comment") return;
			//make line
			var el = new Element('span').inject(officeElement);
			var value = this.getValue(line);
			//get html type
			switch(key) {
				case 'email' : 
					new Element('a', {href : 'mailto:'+value, html : value}).inject(el);
					break;
				case 'site' :
					new Element('a', {href : value, html : value}).inject(el);
					break;
				default :
					el.set('html', value);
					break;
			}
			new Element('span', { html : officeDetails[key] + " : " }).inject(el, 'top');
		}, this);
		
		//hours
		new Element('strong', {html : officeDetails.hours}).inject(officeElement);
		$H(office.hours).each(function(line, key){
			if(key == "comment") return;
			var el = new Element('span', {html : '<span class="detail">' + this.getValue(line) + "</span>" }).inject(officeElement);
			new Element('span', { html : officeDetails[key] + " : " }).inject(el, 'top');
		}, this);
		
		//closure
		if(office.closure) {
			new Element('strong', {html : officeDetails.closure}).inject(officeElement);
			var els = $type(office.closure.line) == 'array' ? office.closure.line : [office.closure.line];
			els.each(function(line, key){
				if(key == "comment") return;
				var el = new Element('span', {html : '<span class="detail closure">' + this.getValue(line) + "</span>" }).inject(officeElement);
			}, this);
		}
		return officeElement;
	},
	
	/* Newsletter footer */
	parseJSONNewsletter : function(json){
		var selected_lang = this.options.lang[0]+'_'+this.options.lang[1];
		//get the office from object
		json.town.each(function(office){
			if(office['@attributes'].lang != selected_lang) return;
			var officeElement = new Element('a',{
				html: officesLanguages[office['@attributes'].name],
				href: this.getURL(office.links[this.options.server]),
				styles: {
					'color': 'rgb(255, 255, 255)',
					'text-decoration': 'none',
					'font-size': '10px',
					'font-weight':'bold'
				}
			})
			officeElement.inject(this.id);
			$(this.id).appendText(' | ');
		}, this);
		var txt = $(this.id).get('html');
		txt = txt .substr(0,(txt.length - 3));
		$(this.id).set('html',txt);
		
		this.fireEvent('complete');
	},
	
	/* Landing page offices phone number */
	parseJSONLanding : function(json){
		var selected_lang = this.options.lang[0]+'_'+this.options.lang[1];
		//get the office from object
		json.town.each(function(office){
			if(office['@attributes'].lang != selected_lang) return;
			var officeElement = new Element('a',{
				html: '<strong>'+this.getValue(office.contact.phone)+'</strong><span>'+officesLanguages[office['@attributes'].name]+'</span>',
				href: this.getURL(office.links[this.options.server]),
				'class': 'offices clearfix'
			});
			
			officeElement.inject(this.id);
		}, this);
		
		this.fireEvent('complete');
	},
	
	
	parseJSONOffice : function(json){
		//get the office from object
		json.town.each(function(office){
			if(office['@attributes'].name != this.options.office) return;
			var officeElement = this.getOfficeFullDetails(office);
			officeElement.inject(this.id);
		}, this);
		
		this.fireEvent('complete');
	},
	
	parseJSONListSimple : function(json){
		this.makeListsVars(json);
		
		//create elements
		var x = new Element('div', {'id' : 'esl-contactQQ'}).inject(this.id);
			
		this.officesList[this.options.lang[1]].each(function(office, town){
			//make a line
			var y = new Element('div').inject(x);
			//add title
			new Element('strong', {'html': 'ESL - '+officesLanguages[town]}).inject(y);
			//add address
			if(office.address.line) office.address.line.each(function(line){
				new Element('span', {'html': ', '+this.getValue(line)}).inject(y);
			}, this);
			//add phone / email
			new Element('span', {'html': ', '+officeDetails.phone+' : '+ this.getValue(office.contact.phone).replace('<br />',' / ')}).inject(y);
			new Element('span', {'html': ', '+officeDetails.email+' : '+ this.getValue(office.contact.email)}).inject(y);
		}, this);
		
		this.fireEvent('complete');
	},
	
	parseJSONList : function(json, detail){
		this.createInterfaceList();
		this.makeListsVars(json);
		this.addOffices(detail);
		
		this.fireEvent('complete');
	},
	
	parseJSONListSlide : function(json){
		// set merge all
		this.options.list = 'complete';
		this.options.showhead = true;
		this.makeListsVars(json);
		
		this.officesList.each(function(country, isocountry){
			//inject country name
			new Element('h2', {html : countriesLanguages[isocountry]}).inject(this.id);
			country.each(function(office, key){
				var c = new Element('div', {'class' : 'office'}).inject(this.id);
				new Element('h3', {html : 'ESL - ' + officesLanguages[key]}).inject(c);
				
				//inject office
				var officeElement = this.getOfficeFullDetails(office);
				officeElement.inject(new Element('div', {'class':'body'}).inject(c));
			}, this);
		}, this);
		
		this.fireEvent('complete');
	},
	
	makeListsVars : function(json){
		if(this.options.list == 'filtered') {
			json.town.each(function(town){
				if(town.links[this.options.server]) {
					var lang = town['@attributes'].lang ? town['@attributes'].lang.split('_') : false;		
					if(lang[0] == this.options.lang[0]) {
						this.officesList[lang[1]] = this.officesList[lang[1]] || new Hash();
						this.officesList[lang[1]][town['@attributes'].name] = town;
					} else {
						this.officesListExtra[lang[1]] = this.officesListExtra[lang[1]] || new Hash();
						this.officesListExtra[lang[1]][town['@attributes'].name] = town;
					}
				}
			}, this);
		} else if(this.options.list == 'complete') {
			json.town.each(function(town){
				if(town.links[this.options.server]) {
					var lang = town['@attributes'].lang ? town['@attributes'].lang.split('_') : false;	
					this.officesList[lang[1]] = this.officesList[lang[1]] || new Hash();
					this.officesList[lang[1]][town['@attributes'].name] = town;
				}
			}, this);
		}
		
		if(this.options.lang[1] == 'CH' && this.officesListExtra.CH && this.options.mergeCountries) {
			//merge same countries, but different language
			this.officesList.CH = this.officesList.CH || new Hash();
			this.officesList.CH.extend(this.officesListExtra.CH);
			delete this.officesListExtra.CH;
		}
	},
	
	makeList : function(list, target, detail, event){
		list.each(function(country, key){
			var position = (this.options.lang[1] == key) ? 'top' : 'bottom';
			var li = new Element('li').inject(target, position);
			var span = new Element('span', {html : '<strong class="country">' + countriesLanguages[key] + '</strong>'}).inject(li);
			
			if(event) span.addEvent('click', function(e){
				this.display(span);
			}.bind(this));
			
			//inject map
			new Element('img', {
				alt : countriesLanguages[key],
				src : '/img/map/mini/'+ key +'.gif'
			}).inject(span);
			
			//create offices list and inject offices
			var ul = new Element('ul').inject(li);
			country.each(function(office){
				detail ? this.injectOfficeDetail(office, ul) : this.injectOffice(office, ul);
			}, this);
		}, this);
	},
	
	addOffices : function(detail){
		//make language cat
		this.makeList(this.officesList, this.list, detail, true);
		
		//make more cat
		var li = new Element('li', {'class' : 'other'}).inject(this.list);
		var span = new Element('span', {html : countriesLanguages.other}).inject(li);
		var other = new Element('ul').inject(li);
		span.addEvent('click', function(e){
			this.display(span, true);
		}.bind(this));
		this.makeList(this.officesListExtra, other, detail, false);
		
		//inject element in page
		$(this).inject(this.id);
		
		//display first cat 
		$(this).getElement('span').fireEvent('click');
	},
	
	injectOffice : function(office, target){
		var off = new Element('li').inject(target);
		
		//inject phone
		if(office.contact && office.contact.phone)
		new Element('span', {html : this.getValue(office.contact.phone)}).inject(off);
		
		//inject link
		if(this.options.links)
			new Element('a', {
				html : officesLanguages.ouroffice + ' ' + officesLanguages[office['@attributes'].name],
				href : this.getURL(office.links[this.options.server])
			}).inject(off);
		else
			new Element('span', {'class': 'a',html : officesLanguages.ouroffice + ' ' + officesLanguages[office['@attributes'].name]}).inject(off);
	},
	
	injectOfficeDetail : function(office, target){
		var off = new Element('li').inject(target);
		
		//inject address
		if(office.address) {
			var a = this.options.links ? 
				new Element('a', {href : this.getURL(office.links[this.options.server])}).inject(off) :
				new Element('span', {'class': 'a',href : this.getURL(office.links[this.options.server])}).inject(off);
			
			office.address.line.each(function(line){
				var span = new Element('span', {html : line, 'class': 'detail'}).inject(a);
			}, this);
		}
		
		//inject phone
		new Element('span', {html : this.getValue(office.contact.phone), 'class' : 'detailphone'}).inject(off);
	},
	
	getValue : function(data){
		switch($type(data)) {
			case 'string' : 
				return data.trim();
			case 'object' :
				//we have the lang?
				var lang = defaultLanguage.substr(defaultLanguage.length-2,2);
				if(data[lang]) return this.getValue(data[lang]);
				//we have the server?
				if(data[this.options.server]) return this.getValue(data[this.options.server]);
				//return first child
				return this.getValue($H(data).getValues()[0]);
		}
	},
	
	getURL : function(cid){
		var url = window.location.protocol + '//' + window.location.host;
		url += '/floor/cs?server=' + this.getServer() + '&lang=' + defaultLanguage + '&item_categoryID=' + cid;
		return url;
	},
	
	getServer : function(){
		if(this.options.server == 'eslagency') {
			switch(defaultLanguage) {
				case 'chfr' :
				case 'chde' :
				case 'chit' :
					var server = 'eslagency';
					break;
				default : 
					var server = 'eslagency' + defaultLanguage.substr(0,2);
					break;
			}
		} else {
			var server = this.options.server;
		}
		
		return server;
	},
	
	display : function(span, other){
		if(this.currentSpan == span) return;
		this.currentSpan = span;
		if (this.active)
			this.active.each(function(el){
				new Fx.Tween(el, {property : 'opacity', onComplete : function(){
					el.removeClass('active');
				}}).start(0);
			});
		if(other) {
			this.active = [
				span.getNext().addClass('active')
			]
		} else {
			this.active = [
				span.getLast().addClass('active'),
				span.getNext().addClass('active')
			]
			new Fx.Tween(span.getLast(), {property : 'opacity'}).start(0,1);
		}
		
		//tween element
		new Fx.Tween(span.getNext(), {property : 'opacity'}).start(0,1);
		
		//tween container
		var target = span.getNext().getHeight()+100;
		if (target < 150) target = 150;
		new Fx.Tween(this, {property : 'height'}).start(target);
	},
	
	convertISOLang : function(){
		if(this.options.lang.split('_').length != 2) {
			switch(defaultLanguage) {
				case 'chfr' :
					var lang = 'fr_CH';
					break;
				case 'befr' :
					var lang = 'fr_BE';
					break;
				case 'fr' :
					var lang = 'fr_FR';
					break;
				case 'chde' :
					var lang = 'de_CH';
					break;
				case 'atde' :
					var lang = 'de_AT';
					break;
				case 'de' :
					var lang = 'de_DE';
					break;
				case 'se' :
					var lang = 'se_SE';
					break;
				case 'es' :
					var lang = 'es_ES';
					break;
				case 'en' :
					var lang = 'fr_CH';
					break;
				case 'cz' :
					var lang = 'cz_CZ';
					break;
				case 'chit' :
					var lang = 'it_CH';
					break;
				case 'it' :
					var lang = 'it_IT';
					break;
				case 'nl' :
					var lang = 'fr_BE';
					break;
				case 'coes' :
					var lang = 'es_CO';
					break;
				case 'paes' :
					var lang = 'es_PA';
					break;
				default :
					var lang = 'fr_CH';
					break;
			}
			this.options.lang = lang;
		}
		
		this.options.lang = this.options.lang.split('_');
	}
});

