/**
 * Blocks manipulation functions.
 *
 * @author (c)2009 Eugene Milovanov, Yuri Dragovoz
 */

var stm = new Object();

var XMLHTTPConnector = new Object();


XMLHTTPConnector.getRequestObject = function() {
	  if (window.XMLHttpRequest) {
    	  return new XMLHttpRequest();
	  } else {
    	 try {
			 return new ActiveXObject("Microsoft.XMLHTTP");			
    	 }   catch (e) 	 {
	    	 return window.createRequest();
    	 } 
	  }
  }
	Boolean.parse = function (str) {
	  switch (str.toLowerCase ()) {
	    case "true":
	      return true;
	    case "false":
	      return false;
	    default:
	      throw new Error ("Boolean.parse: Cannot convert string to boolean.");
	  }
	};

stm.Block = function() {	
	this.interval = null;
	this.clearedProps = new Array();
	this.scalePosition = {block_small_container:"1", block_expanded_container:"2"};
	this.arrowDepict = {block_small_container:"block-caption-moveleft", block_expanded_container:"block-caption-moveright"};
	
	this.blockParams = {};
	this.InstantCache = function() {
		this.cache = new Object();
		this.push = function(key, value) {
				this.cache[key] = value;
			};
		this.load = function(key) {
			return this.cache[key];
		};			
		this.contains = function(key) {
			return this.cache.hasOwnProperty(key);
		};
		this.dropKey = function(value) {
			delete this.cache[value];
		};		
		this.drop = function() {
			this.cache = new Object();
		};
	};
	
	this.instantCache = new this.InstantCache();
	
	this.refreshableBlockIntervals = {};
	
	this.reverseScalePostion = function(destinationId) {
		if (this.scalePosition[destinationId]=="1") return "block_expanded_container"
		if (this.scalePosition[destinationId]=="2") return "block_small_container";
	}
	
	this.reverseArrowDepict = function(destinationId) {
		if (this.arrowDepict[destinationId]=="block-caption-moveleft") return ".block-caption-moveright";
		if (this.arrowDepict[destinationId]=="block-caption-moveright") return ".block-caption-moveleft";
	}
	
	this.rebuildBlocksContainer = {blocksToSave:new Array(), blocksToRemove:new Array()};
	
	this.tempHeadingTitles = {};
	this.headerMouseDelay = null;
	this.tempTitleStorage = new Object();
	this.hoverRoll = function() {
		jQuery(document).ready(function() {
			jQuery('.block-header').hover(function() {
				var jQueryObject = jQuery(this);
				stm.block.headerMouseDelay = setTimeout(function() {
					jQueryObject.find(".caption-buttons > ul").children("li:not([propagatedHidden=true])[hoverable=true]").show();	
					var blockName = jQueryObject.parents('.block').attr('id');
					var tempTitle = null;
					tempTitle = stm.block.tempTitleStorage[blockName] = jQueryObject.find("h2 > span:first").html();
					var currentBlockScale = jQuery("#"+blockName+"Properties").children("INPUT").eq(0).val();
					if (tempTitle!=null && currentBlockScale==1) {
						jQueryObject.find("h2 > span:first").html(tempTitle.length>19?tempTitle.slice(0, 15)+" ...":tempTitle);	
					}	
				}, 100);
			}, function(){
				clearTimeout(stm.block.headerMouseDelay);
				var jQueryObject = jQuery(this);
				jQueryObject.find(".caption-buttons > ul").children("li[hoverable=true]").hide();
				var blockName = jQueryObject.parents('.block').attr('id');
				jQueryObject.find("h2 > span:first").html(stm.block.tempTitleStorage[blockName]);
			});
		});		
	}
	
	this.makeAsyncAjaxCall = function(parameters) {
		setTimeout(function() {
		   var xmlHttp = XMLHTTPConnector.getRequestObject();
		   xmlHttp.onreadystatechange = executedCallBack;	
		   var params = "blockName="+parameters.name+"&scale="+parameters.scale+"&group="+parameters.group;
		   if (stmCache.contains('starKey')) {
			   params+="&starKey="+stmCache.load('starKey');
		   }
		   xmlHttp.open("POST", parameters.relativePath, true);
		   xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		   xmlHttp.setRequestHeader("Content-length", params.length);
		   xmlHttp.setRequestHeader("Connection", "close");
		   xmlHttp.send(params);	
		   function executedCallBack() {
			    if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

			    } 																		    
			}  		
		}, 100);
	}
	
	this.propagateMovementActivity = function(id) {
		var next = this.findNextMovableElement(id);
		var prev = this.findPrevMovableElement(id);
		if (next==null) {
			jQuery("#"+id).find(".block-caption-movedown").eq(0).parent().attr("propagatedHidden", "true");
		} else {
			jQuery("#"+id).find(".block-caption-movedown").eq(0).parent().removeAttr("propagatedHidden");
		}
		if (prev==null) {
			jQuery("#"+id).find(".block-caption-moveup").eq(0).parent().attr("propagatedHidden", "true");
		} else {
			jQuery("#"+id).find(".block-caption-moveup").eq(0).parent().removeAttr("propagatedHidden");
		}
		
		var thisElementMovable = jQuery("#"+id+"Properties").children("INPUT").eq(2).val();
		if (!Boolean.parse(thisElementMovable)) {
			jQuery("#"+id).find(".block-caption-movedown").eq(0).parent().attr("propagatedHidden", "true");
			jQuery("#"+id).find(".block-caption-moveup").eq(0).parent().attr("propagatedHidden", "true");
		}
	}
	
	this.findNextMovableElement = function(id) {
		var nextSibling = jQuery('#'+id).next(".block");
		if (nextSibling==null || nextSibling.attr("id")==null || typeof(nextSibling.attr("id"))=='undefined') return null;
		var movable = jQuery("#"+nextSibling.attr("id")+"Properties").children("INPUT").eq(2).val();
		if (!Boolean.parse(movable)) {
			return this.findNextMovableElement(nextSibling.attr("id"));
		}
		return nextSibling;	
	}
	
	this.findPrevMovableElement = function(id) {
		var previousSibling = jQuery('#'+id).prev(".block");
		if (previousSibling==null || previousSibling.attr("id")==null || typeof(previousSibling.attr("id"))=='undefined') return null;
		var movable = jQuery("#"+previousSibling.attr("id")+"Properties").children("INPUT").eq(2).val();
		if (!Boolean.parse(movable)) {
			return this.findPrevMovableElement(previousSibling.attr("id"));
		}
		return previousSibling;
	}
	/**
	 *
	 * Moves block down on a front page.
	 *
	 * @param  id  id of an element which will be affected
	 * @return      nothing
	 */
	this.moveDown = function(id, scale, group, contextPath) {
		var thisElement = jQuery('#'+id);
		var movable = jQuery('#'+id+"Properties").children("INPUT").eq(2).val();
		if (!Boolean.parse(movable)) return;
		var nextSibling = this.findNextMovableElement(id);
		if (nextSibling==null) return;
		this.makeAsyncAjaxCall({name:id, scale:scale, group:group, relativePath:contextPath+'/block/blockMoveDown.html'});
		
		jq(nextSibling).effect("drop", {mode:"makeInvisible",direction: "up"}, 250);
		jq(thisElement).effect("drop", {mode:"makeInvisible",direction: "down"}, 250, function() {
			var clonedNextElement = nextSibling.clone(true);
			var clonedThisElement = jQuery(this).clone(true);
			nextSibling.after(clonedThisElement).remove();
			jQuery(this).before(clonedNextElement).remove();
			jq(clonedNextElement).effect("drop", {mode:"makeVisible",direction: "down"}, 250);
			jq(clonedThisElement).effect("drop", {mode:"makeVisible",direction: "up"}, 250);
			stm.block.interval =  setInterval('stm.block.propagateAllBlocks()', 50);
		});	
	}	
	
	
	/**
	 *
	 * Moves block up on a front page.
	 *
	 * @param  id  id of an element which will be affected
	 * @return      nothing
	 */
	this.moveUp = function(id, scale, group, contextPath) {	
		var thisElement = jQuery('#'+id);
		var movable = jQuery('#'+id+"Properties").children("INPUT").eq(2).val();
		if (!Boolean.parse(movable)) return;		
		var previousSibling = this.findPrevMovableElement(id);
		if (previousSibling==null) return;
		this.makeAsyncAjaxCall({name:id, scale:scale,group:group, relativePath:contextPath+'/block/blockMoveUp.html'});
		jq(previousSibling).effect("drop", {mode:"makeInvisible",direction: "down"}, 250);
		jq(thisElement).effect("drop", {mode:"makeInvisible",direction: "up"}, 250, function() {
			var clonedPrevElement = previousSibling.clone(true);
			var clonedThisElement = jQuery(this).clone(true);
			previousSibling.before(clonedThisElement).remove();
			jQuery(this).after(clonedPrevElement).remove();
			jq(clonedPrevElement).effect("drop", {mode:"makeVisible",direction: "up"}, 250);
			jq(clonedThisElement).effect("drop", {mode:"makeVisible",direction: "down"}, 250);
			stm.block.interval =  setInterval('stm.block.propagateAllBlocks()', 50);
		});		
	}	
	
	this.truncateBlockNameTitle = function() {
		var jQueryObject = jQuery(this);
		var tempTitle = jQueryObject.find("h2 > span:first").html();
		if (tempTitle!=null) {
			jQueryObject.find("h2 > span:first").html(tempTitle.length>19?tempTitle.slice(0, 13)+" ...":tempTitle);	
		}
	}
	this.changePosition = function(id, destinationId, blockGroup, contextPath) {
		var scale = this.scalePosition[destinationId];
		jQuery("#"+id+"Properties").children("INPUT").eq(0).val(scale);
		
		var clonedElement = jQuery("#"+id).clone(true);		
		
		jQuery("#"+id).fadeOut("fast", function() {												
			if (navigator.userAgent.toLowerCase().indexOf('msie')!=-1) {
				clonedElement.find(stm.block.reverseArrowDepict(destinationId)).get(0).onclick = new Function('evt', 
						"stm.block.changePosition('"+id+"', '"+stm.block.reverseScalePostion(destinationId)+"','"+blockGroup+"','"+contextPath+"'); return false;");
				clonedElement.find(stm.block.reverseArrowDepict(destinationId)).eq(0).attr("class", stm.block.arrowDepict[destinationId]);
			} else {
				clonedElement.find(stm.block.reverseArrowDepict(destinationId)).eq(0).attr("onClick", 
						"stm.block.changePosition('"+id+"', '"+stm.block.reverseScalePostion(destinationId)+"','"+blockGroup+"','"+contextPath+"'); return false;")
				.attr("class", stm.block.arrowDepict[destinationId]);				
			}
			
			jQuery(this).remove();
			clonedElement.css("display", "none");
			jQuery("#"+destinationId).append(clonedElement);			
			
			// call to DB
			stm.block.makeAsyncAjaxCall({name:id, scale:scale, group:blockGroup, relativePath:contextPath+'/block/switchBlockScale.html'});
			var jsonArray = {name:id, scale:scale, contextPath:contextPath, paramsWrap:stm.block.blockParams[id]};
			loadAjaxBlockContent(jsonArray);
			
			if (stm.block.refreshableBlockIntervals.hasOwnProperty(id)) {
				var refreshableObject = stm.block.refreshableBlockIntervals[id];
				clearInterval(refreshableObject.interval);
				jsonArray.noImagePrepend = true;
				refreshableInterval = setInterval(function() {
						loadAjaxBlockContent(jsonArray);
						jsonArray = null;
					}, refreshableObject.refreshTime);
				delete stm.block.refreshableBlockIntervals[id];
				stm.block.refreshableBlockIntervals[id] = {interval:refreshableInterval, refreshTime:refreshableObject.refreshTime};	
			}
			
			stm.block.propagateAllBlocks();
			clonedElement.fadeIn("fast");	
		});

	}
	
	this.removeCommandRunning = false;
	this.removeBlock = function(id, blockGroup, contextPath) {
		if (!confirm("Вы действительно хотите отключить блок '"+jQuery('#'+id).find('H2:first').attr('title')+"?")) return false;
		if (!this.removeCommandRunning) {
			if (id=='blockFiveRandomImagePreview' && imgInterval && imgInterval!=null){
				clearInterval(imgInterval);
			}
			this.removeCommandRunning = true;
			var currentBlockElementObject = jQuery("#"+id);
			currentBlockElementObject.fadeOut("fast", function() {
				var scale = jQuery("#"+jQuery(this).attr("id")+"Properties").children("INPUT").eq(0).val();
				
				// call to DB
				stm.block.makeAsyncAjaxCall({name:id, scale:scale, group:blockGroup, relativePath:contextPath+'/block/remove.html'});
				
				jQuery(this).remove();			
				stm.block.propagateAllBlocks();	
				var absentBlockListElement = jQuery("#refreshBlocksContainer");
				
				if (absentBlockListElement.is(":visible")) absentBlockListElement.fadeOut("fast");
				delete stm.block.blockParams[id];
				stm.block.instantCache.drop();
				stm.block.removeCommandRunning = false;
			});		
		}
	}
	
	this.refreshBlock = function(id, contextPath) {
		var scale = jQuery("#"+id+"Properties").children("INPUT").eq(0).val();
		var jsonArray = {name:id, scale:scale, contextPath:contextPath, paramsWrap:this.blockParams[id]};
		loadAjaxBlockContent(jsonArray);		
	}
	
	this.rebuildBlocks = function(contextPath, groupName) {	
		this.rebuildBlocksContainer.group = groupName;
		   if (stmCache.contains('starKey')) {
			   this.rebuildBlocksContainer.starKey=stmCache.load('starKey');
		   }
		jQuery.ajax({url:contextPath+"/block/rebuildblocks.html", 
			context:document.body, 
			cache:false, 
			async:true,  
			dataType:"html",
			type:"POST",
			data:this.rebuildBlocksContainer,
			beforeSend:function() {
					jq("#refreshBlocksContainerDiv").block({ 
		                message: null,
		                css:{cursor:"wait"},
					    overlayCSS:{opacity: 0.1}
		            }); 
			},
			complete:function(msg) {
				window.location.reload(true);
			},
			error:function(msg) {
				window.location.reload(true);
			}
		});
	}
	
	this.resetBlocks = function(contextPath, groupName) {	
		if (!confirm('Ты действительно хочешь сбросить все настройки положения блоков на этой странице?')) {
			return false;
		}
		var params = new Object();
		params.group = groupName;
		 if (stmCache.contains('starKey')) {
			 params.starKey=stmCache.load('starKey');
		 }
		jQuery.ajax({url:contextPath+"/block/resetBlocks.html", 
			context:document.body, 
			cache:false, 
			async:true,  
			dataType:"html",
			type:"POST",
			data:params,
			beforeSend:function() {
					jq("#refreshBlocksContainerDiv").block({ 
		                message: null,
		                css:{cursor:"wait"},
					    overlayCSS:{opacity: 0.1}
		            }); 
			},
			complete:function(msg) {
				window.location.reload(true);
			},
			error:function(msg) {
				window.location.reload(true);
			}
		});
	}
	
	this.pushBlocks = function(blockName, action) {
		var index = jQuery.inArray(blockName, this.rebuildBlocksContainer[action]);
		if (index==-1) {
			this.rebuildBlocksContainer[action].push(blockName)
		} else {
			this.rebuildBlocksContainer[action].splice(index, 1);
		}
	}
	
	this.loadAbsentBlockList = function(groupName, contextPath, friendKey) {
		var absentBlockListElement = jQuery("#refreshBlocksContainer");
		if (!absentBlockListElement.is(":visible")) {
			if (stm.block.instantCache.contains("absentBlocks")) {
				absentBlockListElement.html(stm.block.instantCache.load("absentBlocks"));
				absentBlockListElement.slideDown("fast");		
				return false;
			}
			var params = (friendKey!=undefined && friendKey!=null && friendKey.length>0)?"group=GUEST_VIEW":"group="+groupName;
			   if (stmCache.extremeContains('starKey') && jQuery.trim(stmCache.load('starKey')).length>0) {
				   params+="&starKey="+stmCache.load('starKey');
			   }
			params+="&noCache="+new Date().getTime();
			jQuery.ajax({url:contextPath+"/block/getAbsentBlockList.html", 
				context:document.body, 
				cache:false, 
				async:true,  
				dataType:"html",
				type:"POST",
				data:params,
				success:function(msg) {
					stm.block.instantCache.push("absentBlocks", msg);
					absentBlockListElement.html(msg);
					absentBlockListElement.slideDown("fast");
				}
			});		
		} else {
			absentBlockListElement.slideUp("fast");
		}
	}
	
	this.propagateAllBlocks = function() {
		this.clearedProps = new Array();
		this.propagateBlock("#block_small_container");
		this.propagateBlock("#block_large_container");
		this.propagateBlock("#block_expanded_container");			
		jQuery(".block .block-header .caption-buttons > ul").find("li[hoverable=true]").hide();	
		jQuery('.block-header').each(function() {
			var jQueryObject = jQuery(this);
			var blockName = jQueryObject.parents('.block').attr('id');
			if (stm.block.tempTitleStorage.hasOwnProperty(blockName)) {
				jQueryObject.find("h2 > span:first").html(stm.block.tempTitleStorage[blockName]);
			}
		});
	}
	
	this.fillDefaultBlockNames = function(friendKey) {
		//:DEPRICATED
	}
	this.propagateBlock = function(id) {
		var wrapped = jQuery(id).children().is(".ui-effects-wrapper");
		if (wrapped) {
			return false;
		} else {
			if (this.interval!=null && this.clearedProps.length==2) {
				clearInterval(this.interval);
			} else {
				this.clearedProps.push(id);
			}
		}		
		var blocks = jQuery(id).children(".block");
		blocks.each(function() {
			stm.block.propagateMovementActivity(jQuery(this).attr("id"));
		});	
	}
	this.toggleFold = function(id, group, contextPath) {
		var elem = jQuery('#' + id + ' > .block-content');	
		var parentElem = jQuery('#' + id);	
		var scale = jQuery("#"+id+"Properties").children("INPUT").eq(0).val();
		//get block status and determine, if we hide block or unhide
		if(elem.is(":visible")) {
			elem.slideUp('normal', stm.block.toggleMinimizeButton(id, true));
		
			// set Opacity to 50% after block slide up
			setTimeout("opacityOn()", 400);			
			opacityOn = function () {
//				stm.block.setOpacity(parentElem.get(0), "5");
				parentElem.css('opacity', '0.5');
			}			
			this.makeAsyncAjaxCall({name:id, scale:scale,group:group, relativePath:contextPath+'/block/minimize.html'});
			jQuery("#"+id+"Properties").children('INPUT').eq(1).val("true");
		} else {
			elem.slideDown('normal', this.toggleMinimizeButton(id, false));	
			parentElem.css('opacity', '1.0');
//			this.setOpacity(parentElem.get(0), "10");
			
			jQuery("#"+id+"Properties").children('INPUT').eq(1).val("false");
			var jsonArray = {name:id, scale:scale, contextPath:contextPath, paramsWrap:this.blockParams[id]};
			loadAjaxBlockContent(jsonArray);
			this.makeAsyncAjaxCall({name:id, scale:scale,group:group, relativePath:contextPath+'/block/maximize.html'});
		}		
	}
	
	this.setOpacity = function(object, value) {
			if (navigator.userAgent.toLowerCase().indexOf("msie")!=-1) {
				object.style.filter = 'alpha(opacity=' + value*10 + ')';	
			} else {
				object.style.opacity = value/10;
			}						
		}

	
	/**
	 *
	 * Minimizes and brings a block on top of a frontpage.
	 *
	 * @param  id  id of an element which will be affected
	 * @return      nothing
	 */
	this.toggleMinimize = function(id) {
		var elem = jQuery('#' + id + ' > .block-content');	
		var parentElem = jQuery('#' + id);	
		//get block status and determine, if we hide block or unhide
		if(elem.is(":visible")) {
			elem.slideUp('normal', stm.block.toggleMinimizeButton(id, true));
		
			// set Opacity to 50% after block slide up
			setTimeout("opacityOn()", 400);			
			opacityOn = function () {
				parentElem.css('opacity',0.5);
			}
			
			//ajax call to DB (save element toggle status)
			// ...
		} else {
			elem.slideDown('normal', this.toggleMinimizeButton(id, false));			
			parentElem.css('opacity',1.0);
			
			//ajax call to DB (save element toggle status)
			// ...
		}
	}
	
	
	/*
	 *
	 * Changes CSS style of a minimize button. If true, set to "plus" sign, if false, set to "minus" sign.
	 *
	 * @param  id  id of an element which will be affected
	 * @param  mode true = hide content, false = unhide
	 * @return      nothing
	 */
	this.toggleMinimizeButton = function(id, mode) {
		if(!mode) { 
			jQuery('#' + id + ' .block-caption-minimize').css('background-position', '-32px 0');
		} else {
			jQuery('#' + id + ' .block-caption-minimize').css('background-position', '-48px 0');
		}
	}	
	
}


stm.block = new stm.Block();




