/************************************************************
		
					Amadori.com / 2011
					
					amadoriNavInterface.js

		<----------------------------------------->
		
		Agency: vanGoGh
		Agency URL: http://vangogh-creative.it
		Author: Federico Weber
		Author URL: http://federicoweber.com

		<----------------------------------------->
			
					TABLE OF CONTENTS
				
				â€¢ DEFINE MVC
					- Slider Model
					- ChekBox Model
					- SlidersPanel Collection
					- MultiToggle Collection
				â€¢ INIT
					- CREATE STATIC GUI ELEMENTS
					- CREATE DINAMIC GUI ELEMENTS 

		<----------------------------------------->
					TODOS
				. Get labels from a JSON


************************************************************/

//on document ready
$(function amadoriNavInterface() {
	"use strict";
	//--------------------------------------------------------------------------> DEFINE MVC

	// This is the Model that controll the slider interface
	var Slider_Model = Backbone.Model.extend({		 	
		defaults : {
			"minValue" : -1, //-1 allow the selection of 0 from the jQuerySlider
			"maxValue" : 11, // 11 allow the selection of 10  from the jQuerySlider
			"value" : 5,
			"id" : this.cid,
			"title" : this.cid 
		},
		// return value property for convenience of use
		value : function(){
			return this.get("value");
		}
	});

	// This is the Collection that contain all the sliders for the interface
	// it is saved to the local storage for recustruction of the menu in diffrent pages

	var SlidersPanel_Collection = Backbone.Collection.extend({
		model: Slider_Model,
		//set the  default name that is used as name for the local storage obj
		name : "slidersPanel",
		
		//create a local storage for the collection is it possible to pass a custom name for it
		setStorage : function(name){
			if (name){
				this.name = name;
			}	
			this.localStorage = new Store(this.name);
		},

		//return an array containig values and id for each slider in the collection [{"id" : string, "value" : num}, {"id" : string, "value" : num}]
		sliders : function(){
			
		},

		//set all the sliders value according to an obj array [{"id" : string, "value" : num}, {"id" : string, "value" : num}]
		update : function(){
			
		},

		//return an array contining the models sorted by the value
		sorted : function(){
			var sorted = _.sortBy(this.models, function(elm){
				return elm.get("value");
			}); 
			return sorted.reverse();
		},

		//return an array contining the ids of the empty values
		getZeroes : function(){
			var zeroes = []; 
			this.each(function(elm){
				if(elm.value() <= 0){
					zeroes.push(elm.id);
				}
			});
			return zeroes;
		}
	});

	//This is the view of the slider
	var Slider_View = Backbone.View.extend({
		tagName : "div",
		className : "amadoriSlider",
		knobAngle : 0,
		// compile the template once for faster rendering
		template :  Handlebars.compile($("#Slider-template").html()) ,

		initialize : function(){
			this.model.bind('change', this.updateGui, this);	
		},

		events : {
			"slide .sliderHolder" : "updateGui",
			"slidechange .sliderHolder" : "updateValue"
		},

		render : function(){
			$(this.el).html(this.template(this.model.toJSON()));	
   			return this;
		},

		updateValue : function(){
			this.model.save({"value" : $("#"+this.model.get("id")+"_slider").slider('value')});
		},

		// This is used to init jquery slider plugin
		updateGui : function(){
			var slidervalue =  $("#"+this.model.get("id")+"_slider").slider('value');
			//update knob
			this.knobAngle = (slidervalue/10)*225;
			$("#"+this.id+" .sliderKnob img").rotate(this.knobAngle);

			//update dots
			var i = 1;
			for(i; i < slidervalue+1; i++){
				$("#"+this.id+"-dash-"+i).removeClass("off").addClass("on");
			}
			for(i = 10; i > slidervalue ; i--){
				$("#"+this.id+"-dash-"+i).removeClass("on").addClass("off");
			}
		},

		initSlider :function(){
			//update slider
			$("#"+this.id+"_slider").slider();
			$("#"+this.id+"_slider").slider( "option" , "max" , this.model.get("maxValue") );
			$("#"+this.id+"_slider").slider( "option" , "min" , this.model.get("minValue") );
			$("#"+this.id+"_slider").slider( "option" , "value" , this.model.get("value") );
		}
	});

	// This is the Model that controll the ChekBox interface
	var ChekBox_Model = Backbone.Model.extend({
		defaults : {
			"checked" : false,
			"id" : this.cid,
			"title" : this.cid 
		},
		toggle : function(silent){
			if(silent)
			{
				this.save({checked: !this.checked()},{silent: true});
			} else {
				this.save({checked: !this.checked()});
			}
				
		},
		// return checked property for convenience of use
		checked : function(){
			return this.get("checked");
		}
	});

	//This is the view for the collection it need a view tmplate to run
	var CheckBox_View = Backbone.View.extend({
		tagName : "li",
		className : "interfaceCheckbox",
		// compile the template once for faster rendering
		template :  Handlebars.compile($("#ChekBox-template").html()) ,

		// bind events from the model
		initialize : function() {
			this.model.bind('change', this.render, this);
		},

		events : {
			"click" : "toggle"
   		},

   		render : function(){

   			$(this.el).html(this.template(this.model.toJSON()));	
   			if(this.model.checked()){
   				$(this.el).removeClass("off").addClass("on");	
   			} else {
   				$(this.el).removeClass("on").addClass("off");	
   			}
   			return this;
   		},

   		toggle : function() {
   			this.model.toggle();
   		}
	});

	// This is the Collection that contain all the Checkbox for the interface
	// if one of the checkbox is changed all the others are changed 
	var MultiToggle_Collection = Backbone.Collection.extend({
		model: ChekBox_Model,

		//set the  default name that is used for the local storage
		initialize: function() {
			this.name = "multiToggle";
			this.bind('change', this.toggleList, this);
		},

		//create a local storage for the collection is it possible to pass a custom name for it
		setStorage: function(name){
			if (name){
				this.name = name;
			}	
			this.localStorage = new Store(this.name);
		},

		//return the checked model
		checked : function(){
			 return this.filter(function(check){ return check.checked(); });
		},

		//toggle all the element if one is changed
		toggleList :function(caller){
			//prevent uncheck current active element
			if(!caller.get("checked")) {
				caller.set({checked: true});	
				caller.change();
			} else {
				//unbind change event to prevent infinity loop
				this.unbind('change');

				//uncheck other elements in the collection
				this.each(function(el){
					if(el.id !== caller.id && el.checked()){
						el.toggle();
					}
				});

				// bind back change event
				this.bind('change', this.toggleList, this);
			}
		}

	});	

	//This is the model for the menu element
	var AmadoriMenuElement_Model = Backbone.Model.extend({
	});

	//This is the view for the single menu entry
	var AmadoriMenuElement_View = Backbone.View.extend({
		tagName : "li",
		className : "menuElement",
		// compile the template once for faster rendering
		template : Handlebars.compile($("#MenuElement-template").html()),

		// bind events from the model
		initialize : function() {
			this.model.bind('change', this.render, this);
		},
		events : {
			"click .imgHolder" : "openUrl",
			"click .description" : "openUrl"
   		},

   		render : function(){
   			$(this.el).html(this.template(this.model.toJSON()));	
   			$(this.el).addClass(this.model.get("size"));
   			return this;
   		},

   		openUrl : function(){
		//by TECLA --from longURL to shortURL --
		var longURL = this.model.get("url");
		var shortURL = longURL.replace('wps/wcm/connect/it/home','site');
   			window.open(shortURL,"_"+this.model.get("target"));
		
			//window.open(this.model.get("url"),"_"+this.model.get("target"));
   		}


	});

	//this is the colleciton that holds all the menu elements
	var AmadoriMenu_Collection = Backbone.Collection.extend({
		model: AmadoriMenuElement_Model,
		//this is used to sort the collection based on the given key criteria 
		organize : function(key){
			// sort the collection based on filters criteria
			this.comparator = function(element){
				return element.get(key);
			};
			this.sort({silent: true});
			return this;
		}
	});

	//this is the model for the twitter feed 
	var TwitterFeed_Model = Backbone.Model.extend({
		
	});

	var TwitterFeed_Collection = Backbone.Collection.extend({
		model: TwitterFeed_Model
	});

	var TwitterFeed_View = Backbone.View.extend({
		tagName: "li",
		className: "tweet",
		template : Handlebars.compile($("#TwitterFeed-template").html()),

		render : function(){
			$(this.el).html(this.template(this.model.toJSON()));
   			return this;
		}
	});

	//This is the view for the menu content
	var AmadoriMenu_View = Backbone.View.extend({
		tagName : "div",
		className : "menuElementsHolder",
		// compile the template once for faster rendering
		template : Handlebars.compile($("#MenuHolder-template").html()),

		name : function(value){
			if(value){
				this.name = value;
			} else {
				return this.name;	
			}
		},

		render : function(){
			$(this.el).html(this.template());	
   			return this;
		}
				
	});

	//This is the twitter feed view

	//This is the view that controll the entire menu app
	var AmadoriMenuApp = Backbone.View.extend({
		el: $("#customMenuInner"), 

		events : {
			"click .bullet" : "scrollTweet"
   		},

		initialize : function(){
			filters.bind('change',   this.updateFilters, this);
			profiles.bind('change',   this.onProfileChanged, this);
			currentProfileData.bind('reset',  this.evaluate, this);
			this.currentProfile = profiles.checked()[0].get("id"); 

			//fire things on by loading the menu data
			this.updateFilters();
			this.loadData();
		},

		loadData : function(){
			//on load create a new collection with all the data related to the profile
			$.getJSON($("#mainAside").data("menuurl")+this.currentProfile+".json",function(data){ //TODO ADD CURRENT PROFILE FOR DISCRIMINATION				
				// add top id if it exist
				if (data.top){
					currentProfileData.top = data.top;
				} else {
					currentProfileData.top = null;
				}

				// add elements to the data collection
				currentProfileData.reset(data.elements);
			});
		},

		evaluate : function(){
			if(this.currentViewElements){
				this.oldViewElements = this.currentViewElementsIds;
			}
			this.currentViewElements = new AmadoriMenu_Collection();

			//sort teh filters
			var sortedFilters = filters.sorted();

			// set all the values as 5 if all filters are == 0
			if(this.zeroesFilters.length === 3)
			{
				this.fillWithAll();		

			} else if(this.zeroesFilters.length === 2){ //fill all the spaces with the remaining filter
				//fill first five element
				currentProfileData.organize(sortedFilters[0].id);
				this.populateMenuData(2, "small");
				this.populateMenuData(4, "big");
				this.populateMenuData(7, "medium");

			} else if(this.zeroesFilters.length === 1){ //divide elemnts evenly among max e min
				//fill first five element
				currentProfileData.organize(sortedFilters[0].id);
				this.populateMenuData(2, "small");
				this.populateMenuData(4, "big");
				//fill last three
				currentProfileData.organize(sortedFilters[1].id);
				this.populateMenuData(7, "medium");

			} else { //divide elements evenly among all three filters in the corret order
				_.each(sortedFilters,function(filter, id){
					//sort the data 
					currentProfileData.organize(filter.id);
					//assign proper size
					switch(id){
						case 0:
							this.populateMenuData(2, "small");
							break;
						case 1:
							this.populateMenuData(4, "big");
							break;
						case 2:
							this.populateMenuData(7, "medium");
							break;
					}
				},this);
			}

			//create the new menu
			this.createNewMenu();
		},

		//this will fill all the spaces using all teh filters 
		fillWithAll : function(){
			//fill first row
			currentProfileData.organize("company");
			this.populateMenuData(2, "small");
			//fill second row
			currentProfileData.organize("entertainment");
			this.populateMenuData(4, "big");
			//fill third row
			currentProfileData.organize("recieps");
			this.populateMenuData(7, "medium");
		},

		populateMenuData : function(till, size){
			var num = currentProfileData.length - 1, i = num, id = "", data; 

			for (i; i >= 0; i --)
			{
				//push the featured id if we are in the second slot and fetured exist
				if (this.currentViewElements.length === 1 && currentProfileData.top){
					data = currentProfileData.get(currentProfileData.top);
					data.set({"size" : "maxi", "image" : data.get("imgmaxi")});
					this.currentViewElements.add(data);
				} else if (this.currentViewElements.length === 1 && !currentProfileData.top){ //set the second elemnt as a top element
					data = currentProfileData.models[i];
					data.set({"size" : "maxi", "image" : data.get("imgmaxi")});
					this.currentViewElements.add(data);
				} else if(this.currentViewElements.length !== 1){	// add id if is different from featured top and we are not in the second position
					data = currentProfileData.models[i];
					id = data.id;
					//add the model if is different from top &&  there is space && the model have not been added already
					if (id != currentProfileData.top && this.currentViewElements.length <= till && !this.currentViewElements.get(id)){
						//set proper size
						data.set({"size" : size, "image" :data.get("img"+size)});
						this.currentViewElements.add(data);			
					}
				}
			}	
		},

		getTwitterFeed : function(){
			// if empty load latest 5 tweets
			if(!this.twitterFeed)
			{
				this.twitterFeed = new TwitterFeed_Collection();
				var user = 'Amadoripeopoll', that = this, text = "", strippedTime, num = 5, kill = false;
				if($.browser.msie && $.browser.version == 7.0){
					num = 1;
				}
				$.getJSON('http://twitter.com/statuses/user_timeline.json?screen_name=' + user + '&count=5&callback=?', function(data)      {
				      
				    _.each(data, function(tweet, id){
				    	text = tweet.text;
				    	strippedTime = tweet.created_at.split(" ");
				    	strippedTime = strippedTime[2]+" "+strippedTime[1]+" "+strippedTime[5];
				    	
				     	// process links and reply
						// text = text.replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, function(url) {
						// 	return '<a target="_blank" href="'+url+'">'+url+'</a>';
						// }).replace(/B@([_a-z0-9]+)/ig, function(reply) {
						// 	return  reply.charAt(0)+'<a href="http://twitter.com/'+reply.substring(1)+'">'+reply.substring(1)+'</a>';
						// });

						//add a model to the twitter colleciton
						if(id < num)
						{
					    	that.twitterFeed.add({"tweet": text, "author": tweet.user.name, "time": tweet.created_at, "strippedTime": strippedTime});
					    }
					});
					that.showTwitter();
				}); 	
			} else {
				this.showTwitter();
			}
		},

		showTwitter : function(){
			this.twitterFeed.each(function(model, id){
				var view =  new TwitterFeed_View({model : model});
				//append view and then add the tweet html
				$("#socialsData ul").append(view.render().el);
				//$(view.render().el).find("article .tweetContent").prepend(view.model.get("tweet"));

				//append bullet
				if(!$.browser.msie && $.browser.version != 7.0){
					if(id === 0){
						$(".twitterHeaderBullets ul").append('<li class="bullet on" data-tweetat="'+id+'"><a href="#"></a></li>');
					} else {
						$(".twitterHeaderBullets ul").append('<li class="bullet off" data-tweetat="'+id+'"><a href="#"></a></li>');
					}
				}
			});
			$(".twitterHeaderBullets ul").css({"margin-left": "-"+((this.twitterFeed.length+1)*13)/2+"px"});
		},

		scrollTweet : function(e){
			if (!e) var e = window.event;	// e gives access to the event in all browsers
			var activeTweet = $(e.target).data("tweetat");
			$("#socialsData ul").animate({ "margin-left" : (-190*activeTweet)+"px" }, 400, 'easeOutCubic'); 
			$(".bullet").removeClass("on").addClass("off");
			$(e.target).removeClass("off").addClass("on");
		},

		updateFilters : function(){	
			this.zeroesFilters = filters.getZeroes();
			this.sortedFilters = filters.sorted();
			this.maxFilter = this.sortedFilters[2];
			this.midFilter = this.sortedFilters[1];
			this.minFIlter = this.sortedFilters[0];	

			if(currentProfileData.length){
				this.evaluate();
			}
		},

		onProfileChanged : function(){
			this.currentProfile = profiles.checked()[0].get("id"); 
			this.loadData();
			//bind back again the change event 
			profiles.bind('change', this.onProfileChanged, this);
		},

		createNewMenu : function(){
			// copy the reference to the current menu if it exist
			if(this.currentMenuView){
				this.currentMenuView.render();
				this.oldMenuView = this.currentMenuView;

			}
			
			//create a new menu
			this.currentMenuView = new AmadoriMenu_View({id : "amadoriMenu_"+Math.ceil(Math.random()*123456789)});
			$("#amadoriMenuCarousel .holder").append(this.currentMenuView.render().el);

			//transition out old menu
			this.animateMenues();

			//populate top menu
			this.populateMenu(".menuTop", 0, 2);
			//populate mid menu
			this.populateMenu(".menuMedium", 3, 4);
			//populate low menu
			this.populateMenu(".menuLow", 5, 7);

			//show twitter feeds
			this.getTwitterFeed();
		},

		populateMenu : function(menuId, start, end){
			var position = 3;
			if (this.currentViewElements.models.length >= end)
			{
				for (var i = end; i >= start; i--){
					var model = this.currentViewElements.models[i];
					var menuEntry = new AmadoriMenuElement_View({model : model, id : model.id});
					$("#"+this.currentMenuView.id+" "+menuId+" .menuContents").prepend(menuEntry.render().el);
					$(menuEntry.el).addClass("elementAt_"+position);
					position --;
				}
			}
		},

		animateMenues :function(){
			// console.log("----> animate main menu");
			if(this.oldMenuView){
				// console.log(this.oldMenuView.el.id);				
				var that = this;
				//animate the main menues to create variance in the speed
				$(".menuMedium").css({"margin-left" : "-300px"}).animate({ "margin-left" : 0+"px" }, 1200);
				$(".menuLow").css({"margin-left" : "-400px"}).animate({ "margin-left" : 0+"px" }, 1400);
				$("#"+this.oldMenuView.el.id).animate({ "margin-left" : "-1200px" }, 700, 'easeOutCubic',function(){
					// destroy old menu
					that.destroyOldMenu();
				}); 		
			}
		},

		destroyOldMenu : function(){
			if(this.oldMenuView){
				// console.log("destroy old menu");
				this.oldMenuView.remove();
				if(this.oldViewElements){
					this.oldViewElements = null;
					// console.log("destroy old view element");
				}
			}
		}
	});
	//DEFINE MVC <----------------------------------------------------------------------------

	//--------------------------------------------------------------------------> INIT

	/*** CREATE STATIC GUI ELEMENTS ***/

	/** append filters title **/
	var profileTitle =  Handlebars.compile($("#TitleHolder-template").html());
	$("#filtersInterface").append(profileTitle({title : "Cosa ti interessa?" , id : "filters"}));
	var titleWidth = $("#filters-title h2").width();
	var holderWidth = $("#filtersInterface").width();
	var dashWidth = (holderWidth - titleWidth)/2;
	$("#filters-title .leftDash, #filters-title .rightDash").width(dashWidth - 5);

	/** append profile title **/
	var profileTitle =  Handlebars.compile($("#TitleHolder-template").html());
	$("#profilesInterface").append(profileTitle({title : "Chi sei?" , id : "profile"}));
	var titleWidth = $("#profile-title h2").width();
	var holderWidth = $("#profilesInterface").width();
	var dashWidth = (holderWidth - titleWidth)/2;
	$("#profile-title .leftDash, #profile-title .rightDash").width(dashWidth - 5);

	/** append list for profile checkboxes **/
	$("#profilesInterface").append("<ul></ul>");

	/*** ------------------------------- ***/

	/*** CREATE DINAMIC GUI ELEMENTS ***/

	/** CREATE the collections **/
	var filters = new SlidersPanel_Collection();
	filters.setStorage("AmadoriMenu-Filters");
	filters.fetch();
	var profiles = new MultiToggle_Collection();
	profiles.setStorage("AmadoriMenu-profiles");
	profiles.fetch();

	/** CHECK LOCAL STORAGE OR CREATE NEW ELEMNTS **/
	if(!filters.length){
		var company = new Slider_Model({"id" : "company", "title" : "azienda"});
		var recieps = new Slider_Model({"id" : "recieps", "title" : "cucina"});
		var entertainment = new Slider_Model({"id" : "entertainment", "title" : "intrattenimento"});
		filters.add(company);
		filters.add(recieps);
		filters.add(entertainment);
	}
	if(!profiles.length){
		var consumer = new ChekBox_Model({"id" : "consumer", "title" : "consumatore"});
		var professional = new ChekBox_Model({"id" : "pro", "title" : "professionista"});
		var press = new ChekBox_Model({"id": "press", "title" : "giornalista / blogger"});
		profiles.add(consumer);
		profiles.add(professional);
		profiles.add(press);
		profiles.get("consumer").toggle();
	}
	/** add the views for each interface element **/
	filters.each(function(filter){
		filter.save();
		var filterView = new Slider_View({model : filter, id : filter.id});
		$("#filtersInterface").append(filterView.render().el);
		filterView.initSlider();
		filterView.updateGui();
	});
	profiles.each(function(profile){
		profile.save(); 
		var profileView =  new CheckBox_View({model : profile, id : profile.id+"_checkbox"});
		$("#profilesInterface ul").append(profileView.render().el);
	});

	/** ADD MAIN APP **/
	window.currentProfileData = new AmadoriMenu_Collection(); //is used to store all the current profile's elements
	window.amadoriMainMenu = new AmadoriMenuApp();
	//amadoriMainMenu.onFiltersChanged();

	//hide navigation elemnts if closed for ie7 overflow bug
	if($("#head_organizza").hasClass('close')){
		$(".interfaceHolder").css({"visibility":"hidden"});
		$(".mainMenuTitle").css({"visibility":"hidden"});
	}

	/*** ------------------------------- ***/


	//INIT<----------------------------------------------------------------------------
}); 
