var Escaparate = Class.create({
	initialize: function( canvas ) {
		this.canvas = $(canvas);
		this.currentProductSet = new DraggableDivManager(); 
		this.countDifferentProductSet = new Hash();  // The different products in set
		this.extraPixels = 45;
		this.canvasXMin = 0;
		this.canvasXMax = 0;
		this.canvasYMin = 0;
		this.canvasYMax = 0;
		this.productBrand = "";
		this.dropping = false; // not repeat onDrop
		this.divLoading = false; //not repear modalBox show
		this.countDifferentProduct = 0;
		this.setId;
		
		var current = this;
		Droppables.add(this.canvas, {
       		onDrop:function(element, dropArea, event)
       		{
       			//not clone draggedDivs
       			if (element.id.indexOf('draggedDiv') == -1 && !this.dropping) {
       				if($('initLabel')) Effect.Puff('initLabel');
       				current.cloneDiv( element, dropArea, event );
       			}
       		}
     	});
		
		Event.observe(canvas ,'click', function (event) {
     		current.disableAllControls();
     	});

     	document.observe('keydown', function(event) {
    		if(event.keyCode == 46) {  //del key
    			escaparate.removeDivKeyPress();
    		}	
		});
     
 	    //initialization of periodical updater SetManager
		this.setManager = new SetManager(this, 20);
	},
	
	cleanCanvas: function () {
		var currentDivsSet = this.currentProductSet.getElements();
		while(currentDivsSet.length != 0)
		{
			for (var i = 0; i < currentDivsSet.length; i++) {
				this.removeDiv(currentDivsSet[i]);
			}
		}
	},
	
	createDivCleanCanvas: function () {
		var contentUrl = "/ajax/canvas/ajaxCreateCleanCanvas";
		new Ajax.Updater(this.canvas, contentUrl, {
		  	method: 'get',
		  	parameters: {
		  		DivId: 'divClean', 
		  		LinkId: 'linkClean'
		  	},
		  	insertion: 'bottom'
		});
	},
	
	createDivSaveCanvas: function (sid) {
		var contentUrl = "/ajax/canvas/ajaxCreateSaveCanvas";
		new Ajax.Updater(this.canvas, contentUrl, {
		  	method: 'get',		 
		  	parameters:{
				setId: sid
			},
		  	insertion: 'bottom'
		});
	},

	configureCanvas: function() {
		var widthBorders = 50;
		var canvasLeft = 0;
		var canvasWidth = parseInt(this.canvas.offsetWidth);
		var canvasTop = 0;
		var canvasHeight = parseInt(this.canvas.offsetHeight);
		this.canvasXMin = canvasLeft - this.extraPixels;
		this.canvasWidth = canvasWidth + (this.extraPixels * 2);
		this.canvasXMax = canvasLeft + canvasWidth + this.extraPixels;
		this.canvasYMin = canvasTop - this.extraPixels;
		this.canvasHeight = canvasHeight + (this.extraPixels * 2);
		this.canvasYMax = canvasTop + canvasHeight + this.extraPixels;
		// alert(this.canvasXMin + ", " + this.canvasXMax + ", " +
		// this.canvasYMin + ", " + this.canvasYMax);
	},
			
	cloneDiv: function(divDropped,dropArea,event)
	{
        var productId = divDropped.getElementsByTagName('input').item(0).value;
        var objType = divDropped.getElementsByTagName('input').item(1).value;
        var imgSrc = divDropped.getElementsByTagName('input').item(2).value;
        var imgSrcMin = divDropped.getElementsByTagName('input').item(3).value;
        	
	    this.dropping = true;

     	event = event ? event : window.event;
     	
     	var initScrollX = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft;
		var initScrollY = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
     	
     	var mouseX = event.clientX + initScrollX;
     	var mouseY = event.clientY + initScrollY;          	

     	// The only way to take the size values, we have to consider that now we don't have
     	//<img> tag.
        var newImg = new Image();
        current = this;
        
        newImg.onload = function (e) {
        	
            var originalWidth = parseInt(newImg.width);
            var originalHeight = parseInt(newImg.height);
            var prop = originalHeight/originalWidth;
            
            if (originalWidth > originalHeight){
            	var newWidth = 120;
            	var newHeight = newWidth*prop;	
            } else{
            	var newHeight = 120;
            	var newWidth = newHeight/prop;
            }
        	

            var newDivLeft = mouseX - current.canvas.offsetLeft - originalWidth / 2;     	
         	var newDivTop = mouseY - current.canvas.offsetTop - originalHeight / 2;         
            
            
            var distLimitX = current.canvasXMax - (newDivLeft + newWidth );
    		if( distLimitX < 0 )
    			newDivLeft = newDivLeft + distLimitX;

    		if( newDivLeft < current.canvasXMin)
    			newDivLeft = current.canvasXMin;            
    	
    		var distLimitY = current.canvasYMax - (newDivTop + newHeight );
    		if( distLimitY < 0 )
    			newDivTop = newDivTop + distLimitY;
    		if( newDivTop < current.canvasYMin )
    			newDivTop = current.canvasYMin;
  
    		var newId = current.createDraggedDiv (newDivTop, newDivLeft, imgSrc, imgSrcMin, newHeight, newWidth, productId, objType);
    		var divName = 'draggedDiv' + newId;
    		var hash = $H({id: divName, width: newWidth, height: newHeight, left: newDivLeft, top: newDivTop,  imageId: 'draggedImg' + newId, 
				imageSrc: imgSrc, imageThumbnailSrc: imgSrcMin, productId: productId, objType: objType, zIndex: 0});
    		current.addProductToCanvas(hash.toJSON());
    		current.updatePanelProducts($(divName), true);
    		current.dropping = false;
        }
        newImg.src = imgSrcMin;
	},
	loadProduct: function(newDivTop, newDivLeft, imgSrc, imgSrcMin, newHeight, newWidth, productId, objType) {
  
		var newImg = new Image();
		current = this;
		

		var newId = this.createDraggedDiv (newDivTop, newDivLeft, imgSrc, imgSrcMin, newHeight, newWidth, productId, objType);
		var divName = 'draggedDiv' + newId;
		var hash = $H({id: divName, width: newWidth, height: newHeight, left: newDivLeft, top: newDivTop,  imageId: 'draggedImg' + newId, 
    		imageSrc: imgSrc, imageThumbnailSrc: imgSrcMin, productId: productId, objType: objType, zIndex: 0});
		this.addProductToCanvas(hash.toJSON());
//		this.updatePanelProducts($(divName), false);
	},
	setCountDifferentProductSet: function(productId) 
	{
		var countProduct = this.countDifferentProductSet.get(productId);
		this.setCountDifferentProduct(countProduct);
		
		if (countProduct == null) {
				//if is null I must valildate the length of different prodducts
			if(this.countDifferentProductSet.keys().length == this.maxDifferentProducts) {
	      		alert(__('El límite máximo por Worldwide Favorites es de %1 productos', [this.maxDifferentProducts]));
	       		return;
	       	}
			countProduct = 0;
		}
		
		if (countProduct >= this.maxProductCopies) {
			alert(__("El Maximo de copias de cada producto es ") + this.maxProductCopies);
			return;
		}
		countProduct = countProduct + 1;		
		this.countDifferentProductSet.set(productId, countProduct);
	},
	setCountDifferentProduct: function(countProduct) 
	{
		this.countDifferentProduct = countProduct;
	},
	getCountDifferentProduct: function() 
	{
		return this.countDifferentProduct;
	},
	createDraggedDiv: function(newDivTop, newDivLeft, imgSrc, imgSrcMin, newHeight, newWidth, productId, objType) 
	{
		//create object draggedDiv with id draggedDiv + caculated id. Rerutn the calculated id 
		
		var idElement = new Date().getTime();
		var newDivId = 'draggedDiv' + idElement;
		var newImgId = 'draggedImg' + idElement;

		var contentUrl = "/ajax/product/ajaxDraggedDiv";
		new Ajax.Updater(this.canvas, contentUrl, {
		  	asynchronous: false,
		  	method: 'get',
		  	parameters: {
		  		newDivId: newDivId, 
		  		newDivTop: newDivTop, 
		  		newDivLeft: newDivLeft,
		  		newImgId: newImgId,
		  		newImg: imgSrc,
		  		newImgMin: imgSrcMin,
		  		newHeight: newHeight,
		  		newWidth: newWidth,
		  		productId: productId,
		  		objType: objType
		  	},
		  	insertion: 'bottom'
		});
		return idElement;
	},
	addProductToCanvas: function(draggedDivJSON)
	{
		draggedDivJSON = draggedDivJSON.evalJSON();
		this.disableAllControls();		
		
        // Control the div of diferents options
        currentProductSet = this.currentProductSet;
		var numOfDivs = currentProductSet.getLength();
				
		this.setCountDifferentProductSet(draggedDivJSON.productId);

		// after charge the newDiv
     	var divNode = $(draggedDivJSON.id);
     	divNode.style.cursor = 'move';

     	this.addProductToSet(divNode);
     	
		// We want to show the options and the button for save the set
		if(this.getCountDivsShowPromos() == 1){		
			//$('contentSaveSetDivProduct').style.display = 'none';
			//$('contentSaveSetDivPromo').show();
			$('saveSetAsPromo').checked = true;
		}else if(numOfDivs == 0) {
			//$('contentSaveSetDivPromo').style.display = 'none';			
			//$('contentSaveSetDivProduct').show();
			$('saveSetAsWantit').checked = true;			
		}
		
		if(numOfDivs == 0) {
			//Effect.SlideDown('saveSetDiv');
			this.createDivCleanCanvas();
			this.createDivSaveCanvas();
		}
     	
     	var dragg = new Draggable(draggedDivJSON.id, {
			   snap: function(x, y, draggable) {
			      function constrain(n, lower, upper) {
			         if (n > upper) return upper;
			         else if (n < lower) return lower;
			         else return n;
			      }
			      var element = draggable.element.getDimensions();
			      return [
			         constrain(x, escaparate.canvasXMin, escaparate.canvasXMax - element.width),
			         constrain(y, escaparate.canvasYMin, escaparate.canvasYMax - element.height)
			      ];
			   },
			   onStart: function (draggable, event) {
			   		escaparate.disableAllControls();
			   		draggable.element.controllable.enableControls();
			   },
			   onEnd: function (draggable, event) {
						//it's affect selected draggedDiv
					draggable.element.controllable.enabled = false;
			   }
			});
			
 		var controllable = new Controllable(divNode,this);
 		divNode.controllable = controllable;
 		
 		imagen = new Image();
 		//imagen.src = imgSrc;
 		imagen.src = draggedDivJSON.imageSrc;
 		//this.imgSrc = imgSrc;
 		this.imgSrc = draggedDivJSON.imageSrc;
 		//this.newImgId = newImgId;
 		this.newImgId = draggedDivJSON.imageId;
 		current = this;
 		
 		if(imagen.complete)
 			$(this.newImgId).src = this.imgSrc;
 		else
 			imagen.onload = function (e) {
 				$(current.newImgId).src = current.imgSrc; 
 			};
	},
	checkPanelProductInit: function ()
	{
		
		var numOfDivs = this.getCountDivsShowProducts();
		
		if (numOfDivs == 0) return true;
			
		return false;
		
	},
	isObjectTypeMyImage: function (element) 
	{
		if (this.getObjectType(element) == 'myImages') { 
			return true;
		}
		return false;
	},
	isObjectTypePredefined: function (element) 
	{
		if (this.getObjectType(element) == 'predefined') {
			return true;
		}
		return false;
	},
	isObjectTypeProduct: function (element) 
	{
		if (this.getObjectType(element) == 'product') {
			return true;
		}
		return false;
	},
	isObjectTypePromo: function (element)
	{
		if(this.getObjectType(element) == 'promo'){
			return true;
		}
		
		return false; 
	},
	getObjectType: function (element)
	{
		var objType = element.getElementsByTagName('input').item(1).value;
		
		return objType; 
	},
	getCountDivsShowProducts: function ()
	{	
		var currentdivs = this.currentProductSet.getElements();
		var numOfDivs = 0;
		
		for(var i = 0; i< currentdivs.length; i++){
			
			if(this.isShowProduct(currentdivs[i])){
				numOfDivs++;
			}
		}
		
		return numOfDivs;
	},
	getCountDivsShowPromos: function ()
	{	
		var currentdivs = this.currentProductSet.getElements();
		var numOfDivs = 0;
		
		for(var i = 0; i< currentdivs.length; i++){
			
			if(this.isObjectTypePromo(currentdivs[i])){
				numOfDivs++;
			}
		}
		
		return numOfDivs;
	},
	isShowProduct: function(element) 
	{
		return (this.isObjectTypeProduct(element) || this.isObjectTypeMyImage(element));
		
	},
	showPanelProductsInit: function() {
		new Ajax.Updater('setProductsPanel', '/canvas/showPanelEscaparatesAndProductsInit', {method: 'get'});
	},
	
	hideSaveDiv: function() 
	{
		//Effect.SlideUp('saveSetDiv');
	},
	updatePanelProducts: function (divNode, asynchronous)
	{	
		
		if (!this.isShowProduct(divNode)) {
			return;
		}
		
		if(this.checkPanelProductInit()) {
			this.hideSaveDiv();
			this.showPanelProductsInit();
		} else {
			var url = '/product/ajaxSetProduct/?noCacheExplorer=' + new Date().getTime();

			var numOfDivs = this.getCountDivsShowProducts(); //count products to determine firstTime
			if (numOfDivs == 1) {
				url +='&firstProduct=true';
				var insertion = false;
			} else {
				var lastProduct = divNode.getElementsByTagName('input').item(0).value;
				if ($('productId'+lastProduct) != null) {
					return; //don't create copy of existent product
				}
				insertion = 'bottom';
			}
			new Ajax.Updater('setProductsPanel', url, {
				method: 'get', 
				asynchronous: asynchronous, 
				evalScripts: true,
				insertion: insertion
			});
		}
	},
	addProductToSet: function (divToAdd)
	{
		var currentProductSet = this.currentProductSet;
		currentProductSet.addDivToFront(divToAdd);
	},	
	showNewSetWindow: function()
	{
		if (this.divLoading) return;
		this.divLoading = true;  //before show modal window sets divLoading
		
		this.setManager.updateChangesDivs(true);
		this.setManager.stop();
		
		var savesSetAsVal = '';
		var saveSetAs = $$('input[name=saveSetAs]:checked').first();

		if( saveSetAs != null){
			savesSetAsVal = saveSetAs.value;
		}

		if(isSession() == '') {	
			Modalbox.show('/suscriber/new', {
					title: __('Antes de crear el set debes estar registrado'), 
					width: 700,
					params: {
						onSaving: 1, 
						savesetas: savesSetAsVal,
						w: parseInt(this.canvasWidth - (this.extraPixels * 2)),
						h: parseInt(this.canvasHeight - (this.extraPixels * 2)),
						extraPixels: this.extraPixels,
						backgroundcolor:  $('canvas').style.background
					},
					afterHide: function() {
						this.divLoading = false;
						this.setManager.start();
					}.bind(this)
				}); 
		} else {
			Modalbox.show('/canvas/createSet/saveSetAs/' + savesSetAsVal, {
					title: __('Antes de publicar...'), 
					width: 600,
					afterHide: function() {
						this.divLoading = false;
						this.setManager.start();
					}.bind(this)
			});
		}
	},
	emptySet: function() {
		return (this.currentProductSet.getLength() <= 0);
	},
	saveSet: function (setName, setDescription)
	{
		var w = parseInt(this.canvasWidth - (this.extraPixels * 2));
		var h = parseInt(this.canvasHeight - (this.extraPixels * 2));
		
		var backgroundcolor = $('canvas').style.background;

		var savesSetAsVal = '';
		var saveSetAs = $$('input[name=saveSetAs]:checked').first();

		if( saveSetAs != null){
			savesSetAsVal = saveSetAs.value;
		}
		var contentUrl = "/ajax/set/ajaxSaveSet";

		new Ajax.Request(contentUrl, {
		  	method: 'get',
		  	parameters: {
				setId: this.setId, 
				setName: setName,
				setDescription: setDescription,
				saveAs: savesSetAsVal,
				w: w,
				h: h,
				backgroundcolor: backgroundcolor,
		  	},
	  		onSuccess: function(transport) {
		  		var response = transport.responseText.split("-");
		  		if (response[0] == "OK") {
		  			this.setId = response[1];
		  			document.location = "/set/detalles/id/" + this.setId;
		  		} else {
		  			alert(response[1]);
		  			this.setManager.start();
		  		}
	  		}
		});
	},
	disableAllControls: function()
	{
		var currentProductSet = this.currentProductSet;
		for( var i = 0; i <currentProductSet.getLength(); i++ )
		{
			currentProductSet.getElement(i).controllable.disableControls();
		}
	},
	removeDiv: function(element)
	{	
		this.currentProductSet.removeDiv( element );
			// actualize the count of different products
		var itemId = element.getElementsByTagName('input').item(0).value;
			
		var count = this.countDifferentProductSet.get(itemId);
		if (count == 1) {
			if(this.isShowProduct(element)) {
				//removeDiv  
				if($('productId'+itemId) != null) {
					$('productId'+itemId).remove();
				}
//				if (this.getCountDivsShowProducts() == 0) {
//					$('divProductsInit').remove();
//				}
			}
			this.countDifferentProductSet.unset(itemId);
		} else {
			this.countDifferentProductSet.set(itemId, --count);
		}
		
		this.setManager.setRemoveDivsId($(element).id);
		this.setManager.updateChangesDivs(true);

		this.canvas.removeChild(element);
		
		if (this.checkPanelProductInit()) { 
			if (this.isShowProduct(element)) {
				this.showPanelProductsInit();
			}
		}
				
		if (this.currentProductSet.getLength() == 0) {
			this.hideSaveDiv();
		}else if (this.getCountDivsShowPromos() == 0) {
			
			if($('contentSaveSetDivPromo').visible()){
				//$('contentSaveSetDivPromo').style.display = 'none';			
				//$('contentSaveSetDivProduct').show();
				$('saveSetAsPromo').checked = false;
				$('saveSetAsWantit').checked = true;
			}
		}
		
		if(element.destroy) {
			element.destroy();
		}
	},
	removeDivKeyPress: function ()
	{
		var currentProductSet = this.currentProductSet;
		for (i = 0; i < currentProductSet.getLength(); i++) {  
			currentProductSet.getElement(i).controllable.delKeyPress();
		}
	},
	elementSelected: function(divToMove)
	{
		this.currentProductSet.elementSelected(divToMove);
	},
	setSetId: function (setId)
	{
		this.setId = setId;	
	},
	showSaveSetWindow: function()
	{
		
		if (this.divLoading) return;
		this.divLoading = true;  //before show modal window sets divLoading

		this.setManager.updateChangesDivs(true);  
		this.setManager.stop();
		
		if(isSession() != '') {
			Modalbox.show('/canvas/createSet/setId/' + this.setId, {
				title: __('Actualizar'), 
				width: 600,
				afterHide: function() {
					this.divLoading = false;
					this.setManager.start();
				}.bind(this)
			});
		}
	},	
	intoCanvas: function (mouseEvent) {
      	var clientX = mouseEvent.clientX;
    	var clientY = mouseEvent.clientY;
    	var offsetRigth = this.canvas.offsetLeft + this.canvas.offsetWidth;
    	var offsetBottom = this.canvas.offsetTop + this.canvas.offsetHeight;
    	var intoCanvasX = (clientX >= this.canvas.offsetLeft && clientX <= offsetRigth);
    	var intoCanvasY = (clientY >= this.canvas.offsetTop && clientY <= offsetBottom);
    	return (intoCanvasX && intoCanvasY);
	}
});

function replaceAll( str, searchTerm, replaceWith, ignoreCase )	{
	var regex = "/"+searchTerm+"/g";
	if( ignoreCase ) regex += "i";
	return str.replace( eval(regex), replaceWith );
}


var DraggableDivManager = Class.create({
	initialize: function( escarapate ) {
		this.divs = Array();
		this.escarapate = escarapate;
		this.separation = 5;
	},
	
	addDivToFront: function( newDiv ){
		var divs = this.divs;
        divs[divs.length] = newDiv;
        this.elementSelected(newDiv); //set the zIndex
    },
    
    getElementIndex: function( element ){
    	var divs = this.divs;
	    for( var i = 0; i < divs.length; i++ )
	    {
			if( element == divs[i] )
	        	return i;
	    }
	    return -1;
	},	

	elementSelected: function (element) {
		this.divSelected = element;
		var current = this;
		
		var escaparate = this.escarapate ;

		if (this.divs.length == 1) {  //the new divs 
			element.style.zIndex = this.separation;
			return;
		} 
				//move to front the div
		var zIndex = parseInt(element.style.zIndex);
		if(zIndex == (this.divs.length) * this.separation) // It's on the front
        	return;
        for (var i = 0; i < this.divs.length; i++) {
        	if (parseInt(this.divs[i].style.zIndex) >= zIndex && this.divs[i] != element) {
        		this.divs[i].style.zIndex = parseInt(this.divs[i].style.zIndex) - this.separation;
        	}
        }
        element.style.zIndex = (this.divs.length) * this.separation;
        
	},	
	removeDiv: function(element)
	{
    	var divs = this.divs;
		for(var i = 0; i<divs.length;i++)
		{
			var item = divs[i];
			
			if(item == element)
			{
				divs.splice(i,1);
			}
		}
		if($('initLabel') && (divs.length == 0) ) {
			this.restoreInitialPanels();
			$('divClean').remove();
			$('divSave').remove();
		}
			
	},
	restoreInitialPanels: function()
	{
		new Effect.Grow('initLabel', {
			afterFinish: function() {
				var initLabel = $('initLabel'); 

				initLabel.style.left = '45px';
				initLabel.style.top = '45px';	
				
				initLabel.style.height = '500px'; 
				initLabel.style.width = '500px';
				
				initLabel.style.position = 'relative';
				initLabel.style.opacity = '';
				initLabel.style.fontSize = '';
			}
		});
	},
	getLength: function()
	{
		return this.divs.length;
	},
	getElements: function()
	{
		return this.divs;
	},
	getElement: function( i )
	{
		return this.divs[ i ];
	}
});

var SetManager = Class.create({
	
	initialize: function(escarapate, timeUpdate) {		
		this.updateSetManager = null;
		this.removeDivsId = Array();
		this.escarapate = escarapate;
		this.timeUpdate = timeUpdate;
		this.url = '/product/ajaxUpdateSetManager';
		this.start();
	},
	start:function()
	{
		this.updateSetManager = new PeriodicalExecuter(function() {   
	            this.updateChangesDivs(false);
	    }.bind(this), this.timeUpdate); 
	        
	    this.updateSet();
	},
	stop:function()
	{
		this.updateSetManager.stop();
	},
	updateSet: function( draggedDivs, removeDivsId) {
		
		new Ajax.Updater('', this.url, {
			  method: 'post',
			  parameters: {
			   		"draggedDivs": 	   draggedDivs,
			   		"removeDivsId[]" : removeDivsId
			   		}
			});
	},
	setRemoveDivsId: function(removeDivId) {		
		
		this.removeDivsId[this.removeDivsId.length] = removeDivId;
	},
	updateChangesDivs: function(special) {
	
		var currentDivsSet = this.escarapate.currentProductSet.getElements();
		
		if(currentDivsSet.length > 0 || special == true) {
			var parameters = Array();
			for (var i = 0; i < currentDivsSet.length; i++) {
				parameters[i] = {'draggedDivId' : $(currentDivsSet[i]).id, 'properties' : this.getDivPropierties(currentDivsSet[i])};
			}
			this.updateSet(parameters.toJSON(), this.removeDivsId);
		}
	},
	getDivPropierties: function(div) {
		var properties = new Array();
		properties = {'div_top': parseInt(div.style.top), 'div_left': parseInt(div.style.left), 'div_with': parseInt(div.style.width),
				 	  'div_height': parseInt(div.style.height), 'div_zIndex': parseInt(div.style.zIndex)};

		return properties;
	}
});	 