/**
 * @author rbrates
 */

var BASE_DOMAIN = window.location.hostname; //document.domain; // used for cookies
var themes = new Array('theme1', 'theme2', 'theme3');
var GRID_UNIT = 200; // grid unit, in px
var IDLE_BOXES_LIMIT = 10;
var idle_coords = [[1200, 200], [200, 800], [1200, 800], [0, 1000], [200, 1200], [0, 1600], [1400, 1600], [1200, 1800], [200, 2200]];

var DropGrid = new Class({
	Implements: [Options, Events],
	
	options: {
		gridWidth: 2000,
		//gridHeight: 3000,
		gridHeight: 4000,
		gridUnit: 200
	},
	
	elements: [],
	
	grid_container: '',
	
	initialize: function(gridContainer, options){
	      this.setOptions(options);
		  this.grid_container = gridContainer;
		  
		  // build the grid's matrix and fill it with false (nothing in there yet)
		  var i = 0;
		  var j = 0;
		  this.grid = new Array();
		  for (w = 0; w < this.options.gridWidth; w += this.options.gridUnit) {
		  	this.grid.push(new Array());
		  	for (h = 0; h < this.options.gridHeight; h += this.options.gridUnit) {
				this.grid[i].push (false);
				j++;
			}
			i++;
		  }
	},
	
	checkDrop: function (coords, drop, element) {

		drop = drop || false;
		element = element || '';
		if (!this.checkBounds(coords)) return false;

		var i = Math.round(coords.left / this.options.gridUnit);
		var j = Math.round(coords.top / this.options.gridUnit);
		var w = Math.round(coords.width / this.options.gridUnit);
		var h = Math.round(coords.height / this.options.gridUnit);
		
		//console.log (i + ' ' + j + ' ' + sz); 
		
		for (si = 0; si < w; si++) {
			for (sj = 0; sj < h; sj++) {
				if (this.grid[i+si][j+sj]) return false;
			}
		}
		
		if (drop) {
			for (si = 0; si < w; si++) {
				for (sj = 0; sj < h; sj++) {
					this.grid[i+si][j+sj] = true;
				}
			}
			//console.log('drop');
			//console.log(JSON.encode(this.grid));	
		}
		
		if (drop && element) {
			this.elements.include($(element));
			this.save();
		}
		
		return true;
	},
	
	clear: function (coords, element) {
		
		element = element || '';	
		
		var i = Math.round(coords.left / this.options.gridUnit);
		var j = Math.round(coords.top / this.options.gridUnit);
		var w = Math.round(coords.width / this.options.gridUnit);
		var h = Math.round(coords.height / this.options.gridUnit);
		var gw = Math.round(this.options.gridWidth / this.options.gridUnit);
		var gh = Math.round(this.options.gridHeight / this.options.gridUnit);
		
		if (this.checkBounds(coords)) {
			for (si = 0; si < w; si++) {
				for (sj = 0; sj < h; sj++) {
					this.grid[i+si][j+sj] = false;
				}
			}
		} else {
			return false;
		}
		
		this.elements.erase($(element));
		
		return true;			

	},
	
	dumpGrid: function () {
		//console.log (JSON.encode(this.grid));
	},
	
	checkBounds: function (coords) {		
		return ((coords.left + coords.width) <= this.options.gridWidth && (coords.top + coords.height) <= this.options.gridHeight)
	},
	
	save: function () {
			
		var elements = [];
		var coords;
		
		this.elements.each(function (el){

			if ($(el)) {
	
				coords = $(el).getCoordinates(this.grid_container);
				//console.log (el.get('id')+ ' ' + JSON.encode(coords));
				elements.push ({
					'id': el.get('id'),
					'coords': coords
				});
				
				//console.log (el.get('id')+ ' ' + JSON.encode(el));	
			}
			
		}, this);
		//console.log('while' + JSON.encode(elements));
		var cookie = Cookie.write('elements', JSON.encode(elements), {duration:60, domain: BASE_DOMAIN, path: '/'});

	},
	
	render: function(elements, drag_options) {

		el_list = elements;
		
		// first see if we have a cookie that already has elements
		saved_elements = JSON.decode(Cookie.read('elements'));
		//console.log (saved_elements);
		
		if (saved_elements) {
			saved_elements.each(function(el) {

				if ($(el.id) && el.id.indexOf('idle') == -1) {
					//console.log('first' + " " + el.id + " " + el.coords.left + " " + el.coords.top)
					$(el.id).setStyles({left: el.coords.left, top: el.coords.top}).fade(1);
					// try to place the element and if we don't succeed, 
					// place it in the first available space
					// (this could happen if sections were placed over 
					// promo elements, while in content pages)

					if (!this.checkDrop(el.coords, true, $(el.id))) {
						this.placeStrayElement($(el.id));
					}
					new Drag.Move($(el.id), drag_options);
					// once placed, remove an element from the array passed in
					el_list.erase($(el.id));
				}
				if ($(el.id) && !el.id.indexOf('idle')) {
					//console.log(el.id + " " + el.coords.left + " " + el.coords.top);
					var clear = this.clear (el.coords, el.id);
				}
			}, this);
		} 
		
		// place the elements that we didn't already have in the cookie
		el_list.each(function(el) {
			if ($(el.id) && el.id.indexOf('idle') == -1) {
				var coords = el.getCoordinates(this.grid_container);
				//console.log('second' + " " + el.id + " " + coords.left + " " + coords.top)				
				if (!this.checkDrop(coords, true, el)) {
					this.placeStrayElement(el);
				}
			}

			new Drag.Move(el, drag_options)

		}, this);	
		
		if (saved_elements) {
			saved_elements.each(function(el) {
				if ($(el.id) && !el.id.indexOf('idle')) {
					//console.log('last' + " " + el.id + " " + el.coords.left + " " + el.coords.top)
					$(el.id).setStyles({left: el.coords.left, top: el.coords.top}).fade(1);
					this.elements.push ({
							'id': el.id,
							'coords': el.coords
						});						

					if (!this.checkDrop(el.coords, true, $(el.id))) {
						this.placeStrayElement($(el.id));
					}
					new Drag.Move($(el.id), drag_options);
					el_list.erase($(el.id));
				}
			}, this);
		}	
		
		if (el_list) {
			el_list.each(function(el) {

				if ($(el.id) && !el.id.indexOf('idle')) {
					var coords = {left: '1200px', top: '200px', width: '200px', height: '200px', right: '1400px', bottom: '400px'}
					//var coords = el.getCoordinates(this.grid_container);
					//console.log('second' + " " + el.id + " " + coords.left + " " + coords.top)				
					//if (!this.checkDrop(coords, true, el)) {
					//	this.placeStrayElement(el);
					//}
				}
	
				//new Drag.Move(el, drag_options)

			}, this);
		}

		//console.log(elements);
		//console.log (this.elements);		
	},
	
	placeStrayElement: function (element) {
		
		if (!element) return;
		
		var coords = element.getCoordinates (this.grid_container);
		//console.log(element.get('id')+" "+coords.left+" "+coords.top);
		var ci = Math.round(coords.left / this.options.gridUnit);
		var cj = Math.round(coords.top / this.options.gridUnit);
		var cw = Math.round(coords.width / this.options.gridUnit);
		var ch = Math.round(coords.height / this.options.gridUnit);
		var gw = Math.round(this.options.gridWidth / this.options.gridUnit);
		var gh = Math.round(this.options.gridHeight / this.options.gridUnit);
		
		// we go through every placement possible
		// and score the viewport points
		var best_placement = {left: 0, top: 0, score: -101};
		for (i = 0; i < gw; i++) {
			//if (!this.checkBounds(element)) break;
			for (j = 0; j < gh; j++) {
				
				sim_left = i*this.options.gridUnit;
				sim_top = j*this.options.gridUnit;
				sim_coords = { left: sim_left, top: sim_top, width: coords.width, height: coords.height }
				if (this.checkDrop(sim_coords)) {
					// check the viewport score
					vwp = Window.getSize();
					element_area = coords.width * coords.height;
					visible_area = (vwp.x - sim_left) * (vwp.y - sim_top) * ((vwp.x < sim_left)&&(vwp.y < sim_top) ? -1 : 1);
					score = visible_area * 100 / element_area;
					
					if (score > best_placement.score) {
						best_placement = {left: sim_left, top: sim_top, score: score};
					}
					 
					//ii = i+1;
					//jj = j + 1;
					//console.log ('vwp.x: ' + vwp.x + ' left: ' + sim_left + ' vwp.y: ' + vwp.y + ' top: ' + sim_top + ' i: ' + ii + ' j: ' + jj + ' score: ' + score);
				}
			}
		}
		
		//console.log (best_placement);
		element.setStyles({left: best_placement.left, top: best_placement.top}).fade(1);
		//console.log(element.get('id')+" "+best_placement.left+" "+best_placement.top);
		this.checkDrop(element.getCoordinates(this.grid_container), true, element);
	}
	 
});

window.addEvent('domready', function() {
	
	// expand the content to fit what it has inside 
	
	if ($('content')) {
		main_content_height = Math.ceil($('content_main').getSize().y / GRID_UNIT) * 20;
		main_content_height = (main_content_height < 20) ? 20 : main_content_height;
		$('content_main').setStyle('height', main_content_height + 'em');
		main_content_height += 19.9;
		$('content').setStyle('height', main_content_height + 'em');
	}
	
	if ($('blog_content')) {
		main_content_height1 = Math.ceil($('blog_left').getSize().y / GRID_UNIT) * 20;
		main_content_height2 = Math.ceil($('blog_right').getSize().y / GRID_UNIT) * 20;

		if (main_content_height1 < main_content_height2)
			main_content_height = main_content_height2;
		else
			main_content_height = main_content_height1;
		main_content_height = (main_content_height < 20) ? 20 : main_content_height;

		$('blog_left').setStyle('height', main_content_height + 'em');
		$('blog_right').setStyle('height', main_content_height + 'em');
		$('blog_content').setStyle('height', main_content_height + 'em');
	}
	
	// images positioning for the main content area (excluding blog)
	if ($('content_main')) {
		
		// fixed image paragraph positioning
		$$('#content_main p').each( function (el) {	
			elPadding = el.getStyle('padding-top');
			elPadding = elPadding.substr(0, elPadding.length-2);

			var currentImgs = el.getChildren('img');

			if (currentImgs.length == 1) {
				imageCoords = [];
				currentImgs.each(function(item, index){
   					imageCoords = item.getCoordinates();
   					imagePadding = item.getStyle('margin-top');
   					item.setStyles({'top': '0px'});
				});
				
				imagePadding = imagePadding.substr(0, imagePadding.length-2);
				var setTop = imageCoords.top - 2*GRID_UNIT - imagePadding - elPadding; //  - 450
				el.setStyles({'top': setTop+"px", 'position': 'absolute'});
			}
		});
		
		// floated text paragraph positioning
		$$('#content_main p').each( function (el) {
			var currentCoords = el.getCoordinates();
			var currentRPadding = el.getStyle('padding-right');
			currentRPadding = currentRPadding.substr(0, currentRPadding.length-2);
			var currentLPadding = el.getStyle('padding-left');
			currentLPadding = currentLPadding.substr(0, currentLPadding.length-2);					
			
			var currentImgs = el.getChildren('img');
			
			if (! currentImgs.length) {
				$$('#content_main p img').each( function (img) {
	
					var imageCoords = img.getCoordinates();
					var imageAlign = img.get('class');
	
				    if (imageCoords.width > 0 && imageCoords.height > 0) {
						
				    	if (imageCoords.top > currentCoords.top && imageCoords.top < currentCoords.bottom || imageCoords.top < currentCoords.top && imageCoords.bottom > currentCoords.top) {
		
							// needs repositioning
							if (imageAlign == 'img_left') {
								var newWidth = currentCoords.width - GRID_UNIT - currentLPadding;
					    		el.setStyles({'margin-left': GRID_UNIT+"px", width: newWidth+"px"});
					    	} else if (imageAlign == 'img_right') {
					    		var newWidth = currentCoords.width - GRID_UNIT - currentRPadding;
					    		el.setStyles({'margin-right': GRID_UNIT+"px", width: newWidth+"px"});			    		
					    	}
				    	}
				    }
				});
			}
		});		
	}	
	
	// downloadable resources
	if ($('downloadable_resource')) {
		$('downloadable_resource').addEvent ('click', function (e) {
		
			if ($('resource_form')) {
				$('resource_form').setStyles({'display': 'block'});				
				
				if ($('reset')) {
					$('reset').addEvent ('click', function (e) {
						$('DownloadName').set('value', '');
						$('DownloadEmail').set('value', '');
						$('DownloadEmail').removeClass('error');
						$('DownloadName').removeClass('error');
						$('resource_form_error1').setStyles({'display': 'none'});
						$('resource_form_error2').setStyles({'display': 'none'});									
						$('resource_form').setStyles({'display': 'none'});
					});
				}
				if ($('DownloadAddForm')) {
					$('DownloadAddForm').addEvent ('submit', function (e) {
						$('DownloadEmail').removeClass('error');
						$('DownloadName').removeClass('error');	
						$('resource_form_error1').setStyles({'display': 'none'});
						$('resource_form_error2').setStyles({'display': 'none'});											
						$('DownloadResource').set('value', $('downloadable_resource').get('rel'));
						
						emailpat = /^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+$/;
						
						var name = $('DownloadName').get('value');
						var email = $('DownloadEmail').get('value');

						if (name.length > 0) {
							if (email.length > 0 && email.test(emailpat)) {						
								$('resource_form').setStyles({'display': 'none'});
							} else {
								$('DownloadEmail').addClass('error');
								$('resource_form_error2').setStyles({'display': 'block'});	
								e.stop();
							}
						} else {
							$('DownloadName').addClass('error');
							$('resource_form_error1').setStyles({'display': 'block'});	
							e.stop();
						}
					});
				}
				
			}
		});
	}
	// style switcher & default theme
	var style_switcher = $('style_switcher');
	
	curr_theme = $('css_theme').get('href');
		
	curr_theme_name = curr_theme.substring(curr_theme.lastIndexOf('/')+1, curr_theme.lastIndexOf('.'));
	curr_theme_path = curr_theme.substring(0,curr_theme.lastIndexOf('/')+1);
	
	saved_theme = Cookie.read('theme');
	
	
	if (saved_theme && curr_theme_name != saved_theme) {
		//var set_saved_theme = new Asset.css(curr_theme_path + saved_theme + '.css', {id: 'css_theme'});
		$('css_theme').set('href', curr_theme_path + saved_theme + '.css');
		
	}
	
	if (style_switcher) {
		
		style_switcher.addEvent ('click', function (e) {
			
			curr_theme = $('css_theme').get('href');
		
			curr_theme_name = curr_theme.substring(curr_theme.lastIndexOf('/')+1, curr_theme.lastIndexOf('.'));
			curr_theme_path = curr_theme.substring(0,curr_theme.lastIndexOf('/')+1);
			/*
			new_theme = themes.getRandom();
			
			while (new_theme == curr_theme_name) {
				new_theme = themes.getRandom();
			}
			
			*/
			
			if (curr_theme_name == themes[0])
				new_theme = themes[1];
			if (curr_theme_name == themes[1])
				new_theme = themes[2];
			if (curr_theme_name == themes[2])
				new_theme = themes[0];	
									
			//var set_theme = new Asset.css(curr_theme_path + new_theme + '.css', {id: 'css_theme'});
			$('css_theme').set('href', curr_theme_path + new_theme + '.css');
			
			var cookie = Cookie.write('theme', new_theme, {duration:60, domain: BASE_DOMAIN, path: '/'});

			if (new_theme == themes[0]) {
				for (ij = 1; ij < IDLE_BOXES_LIMIT; ij++) {
					$('idle'+ij).setStyle('display', 'none');
				}
			} else {
				saved_elements = new Array();
				if (Cookie.read('elements')) {
					saved_elements = JSON.decode(Cookie.read('elements'));				
				}

				for (ij = 1; ij < IDLE_BOXES_LIMIT; ij++) {
					
					var inside = 0;
					if (saved_elements) {
						saved_elements.each(function(el) {
							if (el.id == 'idle'+ij) {
								inside = 1;
							}
						}, this);
					}
					
					$('idle'+ij).setStyle('display', 'block');
					
					//if (saved_elements && !inside) {	
					if (!inside) {
						
						switch(ij)	{
	
							case 1:
								$('idle'+ij).setStyles({left: idle_coords[0][0]+'px', top: idle_coords[0][1]+'px', width: '200px', height: '200px'});									var coords = $('idle'+ij).getCoordinates('drop_grid');
								//console.log(JSON.encode(coords));
								break;
							case 2:
								$('idle'+ij).setStyles({left: idle_coords[1][0]+'px', top: idle_coords[1][1]+'px', width: '200px', height: '200px'})	
								break;
							case 3:
								$('idle'+ij).setStyles({left: idle_coords[2][0]+'px', top: idle_coords[2][1]+'px', width: '200px', height: '200px'})	
								break;	
							case 4:
								$('idle'+ij).setStyles({left: idle_coords[3][0]+'px', top: idle_coords[3][1]+'px', width: '200px', height: '200px'})	
								break;	
							case 5:
								$('idle'+ij).setStyles({left: idle_coords[4][0]+'px', top: idle_coords[4][1]+'px', width: '200px', height: '200px'})	
								break;
							case 6:
								$('idle'+ij).setStyles({left: idle_coords[5][0]+'px', top: idle_coords[5][1]+'px', width: '200px', height: '200px'})	
								break;	
							case 7:
								$('idle'+ij).setStyles({left: idle_coords[6][0]+'px', top: idle_coords[6][1]+'px', width: '200px', height: '200px'})	
								break;
							case 8:
								$('idle'+ij).setStyles({left: idle_coords[7][0]+'px', top: idle_coords[7][1]+'px', width: '200px', height: '200px'})	
								break;	
							case 9:
								$('idle'+ij).setStyles({left: idle_coords[8][0]+'px', top: idle_coords[8][1]+'px', width: '200px', height: '200px'})	
								break;																																												
						}	
	
						$('idle'+ij).coords = $('idle'+ij).getCoordinates(grid.grid_container);
						if (!grid.checkDrop($('idle'+ij).coords, true, $('idle'+ij) )) {	
							grid.placeStrayElement($('idle'+ij));
						}
	
						saved_elements.push ({
							'id': 'idle'+ij,
							'coords': $('idle'+ij).coords
						});
					}
				}	

				var cookie = Cookie.write('elements', JSON.encode(saved_elements), {duration:60, domain: BASE_DOMAIN, path: '/'});		
			}
			
			return false;
		});
	}
	
	var style_switcher1 = $('style_switcher1');
	
	if (style_switcher1) {
		style_switcher1.addEvent ('click', function (e) {
			$('css_theme').set('href', curr_theme_path + themes[0] + '.css');
			var cookie = Cookie.write('theme', themes[0], {duration:60, domain: BASE_DOMAIN, path: '/'});
		});
	}	
	
	var style_switcher2 = $('style_switcher2');
	
	if (style_switcher2) {
		style_switcher2.addEvent ('click', function (e) {
			$('css_theme').set('href', curr_theme_path + themes[1] + '.css');
			var cookie = Cookie.write('theme', themes[1], {duration:60, domain: BASE_DOMAIN, path: '/'});
		});
	}
	
	var style_switcher3 = $('style_switcher3');
	
	if (style_switcher3) {
		style_switcher3.addEvent ('click', function (e) {
			$('css_theme').set('href', curr_theme_path + themes[2] + '.css');
			var cookie = Cookie.write('theme', themes[2], {duration:60, domain: BASE_DOMAIN, path: '/'});
		});
	}	
		
	
	// reset everything 
	
	var reset_xp = $('reset_xp');
	
	if (reset_xp) {
		reset_xp.addEvent ('click', function (e) {
			Cookie.dispose('theme', {domain: BASE_DOMAIN, path: '/'});
			Cookie.dispose('elements', {domain: BASE_DOMAIN, path: '/'});
			window.location.reload();
			return false;
		});
	}

	// fix Moz/Opera focus bug
	if ($('BlogName')) {
		$('BlogName').addEvent ('click', function (e) {
			this.focus();
		});
	}
	if ($('BlogEmail')) {
		$('BlogEmail').addEvent ('click', function (e) {
			this.focus();
		});
	}	
	if ($('BlogWebsite')) {
		$('BlogWebsite').addEvent ('click', function (e) {
			this.focus();
		});
	}
	if ($('BlogContent')) {
		$('BlogContent').addEvent ('click', function (e) {
			this.focus();
		});
	}		

	// add drag and drop functionality
	
	var grid = new DropGrid($('drop_grid'));
	var initial = [];
	var transit = [];
	var scroller = new Scroller (window);
	
	var dragOptions = {
	    snap: 5,
		grid: 200,
		container: 'drop_grid',
		preventDefault: true,
		
	    onSnap: function(el){
	    	

		    	
				// cancel event bubbling
				el.addEvent('click', function (e) {
					this.removeEvents('click');
					e.stop();
				}.bind(el));
	
		        el.addClass('in_drag');
				el.fade(0.6);
				var coords = el.getCoordinates('drop_grid');
	
				initial = coords;
				transit = coords;				
	
				var clear = grid.clear (coords, el.get('id'));

				scroller.start();
	

	    },
		
	    onComplete: function(el){


		        el.removeClass('in_drag');
				el.removeClass('droppable');
				el.removeClass('not_droppable');
				el.fade(1);
				
				var name = this.element.get('id');
				
				var coords = el.getCoordinates('drop_grid');
				//console.log(JSON.encode(coords));

				var dropped = grid.checkDrop (coords, true, name);

				var inBounds = grid.checkBounds (coords);
				
				// if the square is not in bounds, it means it needs to be removed
				if (!inBounds) {
					this.element.fade(0);
				} else {
					// if the square couldn't be dropped, then 
					// return it to its initial place
					if (!dropped) {
						var getBack = new Fx.Morph(el, {duration: 300, transition: Fx.Transitions.Elastic.easeOut});
	
						getBack.start({
						    'left': initial.left,
						    'top': initial.top
						}).chain(
							function() {
												
								// if it still wasn't dropped, it means 
								// it came from the list or was dropped on the list
								coords = this.element.getCoordinates('drop_grid');
								dropped = grid.checkDrop (coords, true, name);
								inBounds = grid.checkBounds (coords);
								
								if (!dropped | !inBounds) {
									this.element.fade(0);
								}
							}
						);
					}		
				}
	
				scroller.stop();
				
	    },
		
		onDrag: function (el) {
			el.removeClass ('not_droppable');
			el.removeClass ('droppable');
/*
			if (transit.width && transit.height) {
				var coords = transit;
				transit = [];
			} else { 
				var coords = el.getCoordinates('drop_grid');
			}
*/			
			var coords = el.getCoordinates('drop_grid');
			
			var droppable = grid.checkDrop (coords);

			if (droppable) {
				el.removeClass ('not_droppable');
				el.addClass ('droppable');
			} else {
				el.removeClass ('droppable');
				el.addClass ('not_droppable');
			}

		}
	};
		
		
	// effect for showing the content on promo boxes
	$$('#drop_grid div.promo').each( function (el) {
		
		var face = el.getChildren()[0];
		var back = el.getChildren()[1];
		
		var face_anim = new Fx.Morph(face, {wait: false, unit: 'em', duration: 300, transition: Fx.Transitions.Elastic.easeOut});
		var back_anim = new Fx.Morph(back, {wait: false, unit: 'em', duration: 300, transition: Fx.Transitions.Elastic.easeOut});
		
		el.addEvent('mouseenter', function(e) {
			face_anim.start({'margin-left': -20});
			back_anim.start({'margin-left': -20});
		});
		el.addEvent('mouseleave', function(e) {
			face_anim.start({'margin-left': 0});
			back_anim.start({'margin-left': 0});
		});
		
	});
	
	
	// background flash for main sections
	$$('#drop_grid div.section').each( function (el) {
		
		var bg_flash = new Fx.Morph(el.getChildren()[0], {wait: false, duration: 500, transition: Fx.Transitions.Elastic.easeOut}).set({
			'opacity': 0
		});
		
		el.addEvent('mouseenter', function(e) {
			bg_flash.start({'opacity': 0.7});
		});
		el.addEvent('mouseleave', function(e) {
			bg_flash.start({'opacity': 0});
		});
		
	});
	
	// finally, render the grid
	
	grid.render ($$('#drop_grid div.draggable'), dragOptions);
});