$.onready(function(){
	UserAgent.setupDocumentElementClassNames()
	IngredientPopup.bootstrap()
	
	var aniOpts = {animationType: 'easeInOutCubic'};
	new RollingImagesLite($('recommendations'), aniOpts);
	new RollingImagesLite($('related'), aniOpts);
	new RollingImagesLite($('ingredients'), aniOpts);
	Controller.init();
	Calculator.init();
	
	ShareButtons.bootstrap({text: 'Коктейль «' + Controller.name + '»'})
})

;(function(){

var Me =
{
	bootstrap: function (params)
	{
		var frame = $$('#share .frame')
		if (!frame || !frame[0]) // bad
			return
		
		frame = frame[0]
		frame.src = '/share-buttons.html?url=' + encodeURIComponent(location.href) + '&text=' + encodeURIComponent(params.text)
	}
}

Me.className = 'ShareButtons'
self[Me.className] = Me

})();

var Model = {
	cocktail: null,
	ingredients: [],
	
	dataListener: null,
	
	recs: [], // recommendations
	
	init: function(name){
		this.cocktail = Cocktail.getByName(name);
		
		var ingredients = this.ingredients = Ingredient.mergeIngredientSets(this.cocktail.ingredients, this.cocktail.garnish)
		for (var i = 0, il = ingredients.length; i < il; i++)
			ingredients[i] = Ingredient.getByName(ingredients[i][0])
		ingredients.sort(Ingredient.compareByGroup)
		
		this.related = this._findRelated(this.cocktail).slice(0, 15)
		
		// var all = Cocktail.getAll()
		// var max = 0
		// for (var i = 0, il = all.length; i < il; i++)
		// {
		// 	var begin = new Date()
		// 	this._findRelated(all[i])
		// 	var diff = new Date() - begin
		// 	if (diff > max)
		// 	{
		// 		max = diff
		// 		log(all[i].name, diff)
		// 	}
		// }
		
		this.recs = this._findRecs(this.cocktail);
		if(this.recs.length == 0) this.dataListener.expandRelated();
	},
	
	_findRecs: function(cocktail){
		var recs = [];
		var ingreds = cocktail.ingredients; 
		
		for(var i = 0; i < ingreds.length; i++){
			var items = Ingredient.getByName(ingreds[i][0])
			if(items && items.mark && this._doesntHave(recs, items.mark)){
				var rec = {};
				rec.mark  = items.mark;
				recs.push(rec);
			}
		}
		return recs;
	},
	
	_findRelated: function (source)
	{
		// var begin = new Date()
		// console.time('_findRelated')
		
		var namesHash = DB.hashIndex(source.getIngredientNames()),
			tagsHash = DB.hashIndex(source.tags)
		
		var match = []
		
		var all = Cocktail.getAll()
		for (var i = 0, il = all.length; i < il; i++)
		{
			var cocktail = all[i]
			
			// kick out the source cocktail :)
			if (cocktail == source)
				continue
			
			var weight = 0
			
			// weight by ingredients
			var names = cocktail.ingredients
			for (var j = 0, jl = names.length; j < jl; j++)
				if (namesHash[names[j][0]])
					weight += 6
				else
					weight -= 2
			
			// // forget it if there are no common ingredients
			// if (weight <= 0)
			// 	continue
			
			// weight by tags
			var tags = cocktail.tags
			for (var j = 0, jl = tags.length; j < jl; j++)
				if (tagsHash[tags[j]])
					weight += 2
			
			match.push(cocktail)
			cocktail.__relatedWeight = weight
		}
		
		// if you serach the bottleneck in IE, here it is:
		match.sort(function (a, b) { return b.__relatedWeight - a.__relatedWeight })
		
		// alert(new Date() - begin)
		// console.timeEnd('_findRelated')
		
		return match
	},
	
	/**
	 * Нет ли бренда уже в списке рекомендуемых
	 * Проверяет первое слово в названиях
	 */
	_doesntHave: function(recs, name){
		for(var i = 0; i < recs.length; i++){
			if(recs[i].mark == name) return false;
		}
		return true;
	},
	
	getCocktailByName: function (name)
	{
		return Cocktail.getByName(name)
	}
}

Array.prototype.random = function() {
	var len = this.length
	if (len)
		return this[Math.round(Math.random() * (len - 1))]
}

var Controller = {
	NAME_ELEM  : 'cocktail_name',
	ID_REC     : 'recommendations',
	ID_REC_SUR : 'rec_surface',
	
	ID_ILLUSTRATION : 'cocktail-image',
	
	ID_AUTHOR : 'author',
	SELECTOR_AUTHOR : 'a.author',
	ID_WHERE_TO_TASTE : 'where-to-taste',
	
	ID_RELATED : 'related',
	ID_REL_SUR : 'rel_surface',
	ID_REL_VPR : 'rel_viewport',
	
	ID_ING       : 'ingredients',
	ID_ING_SUR   : 'ingreds_surface',
    ID_INGS_LIST : 'ingredients_list',
	
	REL_WIDTH_SMALL : '330px',
	REL_WIDTH_BIG   : '560px',
	
	ID_CART_EMPTY   : 'cart_draghere',
	ID_CART_FULL    : 'cart_contents',
	
	CLASS_PRINT_RECIPE : '.bt-print-how',
	KEY_ESC: 27,
	
	name : "",
	relatedCount: 10,
	
	nodes:
	{
		moreBox: $('b-more'),
		hreview: $$('.hreview')[0],
		showRecipe: $('show-recipe'),
		hideRecipe: $('close-recipe'),
		showLegendBtn: $('show-legend'),
		hideLegendBtn: $('hide-legend')
	},
	
	init: function(){
		this.name = $(this.NAME_ELEM).getAttribute('data-cocktail-name');
		this.DROP_TARGETS = [$(this.ID_CART_EMPTY), $(this.ID_CART_FULL)];
		new Draggable($(this.ID_ILLUSTRATION), this.name, this.DROP_TARGETS);
	    
		Model.dataListener = this;
		this.bindEvents(this.name);
		Model.init(this.name);
		var perPage = 5;
		if(Model.recs.length > 0) {
			this.renderRecommendations(Model.recs);
			perPage = 3;
		} else this.expandRelated();
		this.renderRelated(perPage);
		this.renderIngredients(Model.ingredients);
	},
	
	bindEvents: function(name){
		var self = this;
		
		var barman = Barman.getByCocktailName(name)
		if (barman)
		{
			var a = $(this.ID_AUTHOR)
			if (a)
			{
				a.removeClassName('hidden')
				a.href = barman.pageHref()
			}
			
			
			a = $$(this.SELECTOR_AUTHOR)[0]
			if (a)
			{
				a.addClassName('active')
				a.href = barman.pageHref()
			}
		}
		
		var bars = Bar.getByCocktailName(name)
		if (bars.length)
		{
			var a = $(this.ID_WHERE_TO_TASTE)
			a.removeClassName('hidden')
			
			if (bars.length == 1)
			{
				a.href = bars[0].pageHref()
			}
			else
			{
				a.href = '/bars.html#cocktail=' + encodeURIComponent(name)
			}
		}
		
		this.nodes.showRecipe.addEventListener('click', function(e){
			Statistics.cocktailViewRecipe(Cocktail.getByName(self.name))
			
			var root = self.nodes.hreview
			root.removeClassName('state-initial')
			root.addClassName('state-recipe')
			
			var ri = $(self.ID_ING).RollingImagesLite
			if (ri)
				ri.goInit(); // Work-around for RI: FIXME
		}, false);
		
		this.nodes.hideRecipe.addEventListener('click', function (e)
		{
			var root = self.nodes.hreview
			root.removeClassName('state-recipe')
			root.addClassName('state-initial')
		},
		false)
		
		if (this.nodes.showLegendBtn)
		{
			this.nodes.showLegendBtn.addEventListener('click', function (e)
			{
				Statistics.cocktailViewLegend(Cocktail.getByName(self.name))
			
				var root = self.nodes.hreview
				root.removeClassName('state-initial')
				root.addClassName('state-legend')
			},
			false)
			
			this.nodes.hideLegendBtn.addEventListener('click', function (e)
			{
				var root = self.nodes.hreview
				root.removeClassName('state-legend')
				root.addClassName('state-initial')
			},
			false)
		}
		
		var printRecipe = $$(this.CLASS_PRINT_RECIPE)[0]
		printRecipe.addEventListener('click', function (e)
		{
			window.open('/print_cocktail.html#' + encodeURIComponent(self.name))
		}, false);
		
		var tools_links = $$(".b-content .tools dd a");
		for (var i = 0; i < tools_links.length; i++){
			var tool = Ingredient.getByName(tools_links[i].innerHTML)
			// FIXME: dirty fix for invalid tool name
			// was cached in html while js had been updated
			if (!tool)
			{
				tools_links[i].parentNode.hide()
				continue
			}
			tools_links[i].addEventListener('click', function(tool){ return function(e){
				self.showIngredientPopup(tool)
			}}(tool), false);
		}
	
		$(self.ID_INGS_LIST).addEventListener('click', function (e) { self.mayBeIngredientClicked(e.target) }, false)
    },
	
	mayBeIngredientClicked: function (node)
	{
		var name = node.getAttribute('data-ingredient-name')
		var ingredient = Ingredient.getByName(name)
		if (ingredient)
			this.showIngredientPopup(ingredient)
	},
	
	renderRecommendations: function(recs){
		var ri = $(this.ID_REC).RollingImagesLite;
		var parent = $(this.ID_REC_SUR);
		
		for(var i = 0; i < recs.length; i++){
			var div = this._createRecommendationElement(recs[i], i);
			parent.appendChild(div);
		}
		
		if(recs.length > 1){
			parent.appendChild(this._createRecommendationElement(recs[0], i));
			switchFrame = function(){
				var len = ri.points.length
				var cur = ri.current
				
				if(cur == len-2) {
					var animation = ri.goToFrame(cur+1);
					animation.oncomplete = function(){
						ri.goToFrame(0, 'directJump');
					};
				} else {
					ri.goToFrame(cur+1);
				}
			}
			var frameSwitchTimer = setInterval(switchFrame, 2500);
			var removedLast = false;
			parent.addEventListener('mouseover', function(){ 
				clearInterval(frameSwitchTimer);
				if(!removedLast){
					parent.removeChild(parent.lastChild);
					ri.sync();
					removedLast = true;
				}
			}, false);
		}
		ri.sync();
		ri.goInit();
	},
	
	_createRecommendationElement: function (rec, num)
	{
		var point = document.createElement("a");
		point.className = "point";
		point.id = "rec_"+(num+1);
        point.href = Ingredient.ingredientsLinkByMark(rec.mark);
		
		var mark = Mark.getByName(rec.mark)
		if (mark)
		{
			var banner = document.createElement('img')
			banner.src = mark.getBannerSrc()
			banner.alt = mark.name
			point.appendChild(banner)
		}
		else
			point.appendChild(document.createTextNode(rec.mark))
		
		return point;	
	},
	
	renderRelated: function (perPage)
	{
		var resultSet = Model.related,
			root = $(this.ID_REL_VPR)
		
		root.style.width = (perPage == 3) ? this.REL_WIDTH_SMALL : this.REL_WIDTH_BIG;
		
		$(this.ID_REL_SUR).empty()
		var np = this._getNumOfPages(resultSet, perPage);
		for(var i = 1; i <= np; i++) {
			var selectedSet = resultSet.slice((i-1)*perPage, i*perPage);
			this._renderPage(selectedSet, i, perPage);
		}
		$(this.ID_RELATED).RollingImagesLite.sync();
		$(this.ID_RELATED).RollingImagesLite.goInit();
	},

	showIngredientPopup: function (ingredient)
	{
		IngredientPopup.show(ingredient)
	},
	
	renderIngredients: function(ingredients) {
		var perPage = 3;
		var np = this._getNumOfPages(ingredients, perPage);
		
		for(var i = 1; i <= np; i++) {
			var selectedSet = ingredients.slice((i-1)*perPage, i*perPage);
			this._renderIngPage(selectedSet, i);
		}
		
		$(this.ID_ING).RollingImagesLite.sync();
		$(this.ID_ING).RollingImagesLite.goInit();
	},
	
	_renderIngPage: function(resultSet, pageNum) {
		var self = this;
        var parent = $(this.ID_ING_SUR);
		var div = document.createElement("div");
		div.className = "point";
		div.id = "ing_" + pageNum;
		parent.appendChild(div);
		
		for (var i = 0; i < resultSet.length; i++)
		{
			var ingredient = resultSet[i]
			var img = document.createElement("div");
			img.className = 'image'
			img.style.backgroundImage = 'url(' + ingredient.getMiniImageSrc() + ')'
			img.alt = ingredient.name;
            img.addEventListener('click', function(ingredient) { return function(){
                self.showIngredientPopup(ingredient);
            }}(ingredient), false);
			div.appendChild(img);
		}
	},
	
	_getNumOfPages: function(resultSet, perPage) {
		if ((resultSet.length % perPage) == 0) return (resultSet.length/perPage);
		return parseInt(resultSet.length / perPage) + 1;
	},
	
	_renderPage: function(resultSet, pageNum, perPage){
		var parent = $(this.ID_REL_SUR);
		
		var page = document.createElement("div");
		page.id = "page_" + pageNum;
		page.className = "point";
		page.style.width = (perPage == 3) ? this.REL_WIDTH_SMALL : this.REL_WIDTH_BIG;
		parent.appendChild(page);
		
		var ul = document.createElement("ul");
		ul.id = "ul_" + pageNum;
		page.appendChild(ul);
		
		for (var i = 0; i < resultSet.length; i++) {
			ul.appendChild(this._createCocktailElement(resultSet[i]));
		}
	},
	
	_createCocktailElement: function (cocktail)
	{
		var node = cocktail.getPreviewNode()
		new Draggable(node.img, cocktail.name, this.DROP_TARGETS)
		return node
	},
	
	expandRelated: function ()
	{
		this.nodes.moreBox.addClassName('wide')
	}
}


