﻿jQuery.extend(jQuery.expr[':'], {
    focus: function(element) { 
        return element == document.activeElement; 
    }
});


/**
@class Static class with all authentication functionality
*/ 
var Login = {};

Login.UpdateGuiOnUserLoggedIn = function(username)
{
	$('.user-logged-out').hide();
	$('.user-logged-in').show();
	$('.user-logged-in .username').html(username);
}

Login.DeleteAllCookies = function ()
{
	var cookies = document.cookie.split(";");

	for (var i = 0; i < cookies.length; i++)
	{
		var cookie = cookies[i];
		var eqPos = cookie.indexOf("=");
		var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
		var shouldDelete = (name != 'im-is-registered')
		if (shouldDelete)
		{
			document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
		}
	}
}

/**
@class Static class with all generic editor functionality.
*/ 
var Editor = {};

/** Determines whether user is saving or publishing */
Editor.isPublishing = false;


/** Determines whether user is currently dragging or resizing a VisualBox */
Editor.isDraggingOrResizingNow = false;

/** Determines whether we're currently showing a dialog */
Editor.isShowingDialog = false;

/** Determines whether we're currently in edit mode */
Editor.isInEditMode = false;

/** Determines which submenu is currently displayed */
Editor.currentSubMenu = 'clear';

/** Determines whether user is currently focused on the XML serialization textarea */
Editor.inXmlArea = false;

/** The clipboard of the application */
Editor.clipboard = null;
Editor.clipboard_time = 0;

/** Specifies whether the editor is active */
Editor.active = true;

/** Specified the editor mode */
Editor.mode = null;

/** Is in demo mode? */
Editor.modeDemo = false; 

/** Is debug mode active? */
Editor.debugMode = false;

Editor.previousSubMenu = '',

/** Helper array when dragging elements, used to save distance between all marked elements:
Example structure: ['VBID1'=>[0,0]], ['VBID1'=>[241,453]], ['VBID1'=>[-281,-22]] */
Editor.dragOffsetsByVbid = Array();

/** Associative array of PictureBoxes which were loaded. Used for website generator */
Editor.pictureBoxesLoaded = Array();

/** Website Generator: are all the pictures loaded yet? */
Editor.allPicturesLoaded = false;

/** Website Generator: are all the fonts loaded yet? */
Editor.allFontsLoaded = false;

Editor.pendingClones = Array();

//===================================== INITIALIZATION FUNCTIONS ======================================//

/**
Determines whether the editor is active.
@returns	{Boolean}	Returns 'true' if the editor is active, 'false' if unactive.
*/
Editor.IsActive = function()
{
	return Editor.active;
}

/**
Toggles the editor mode
@param {String} mode	The current editor mode: 'edit', 'preview', 'view'.
*/
Editor.ToggleMode = function(mode)
{
	console.log('Toggling to mode: ', mode);
	$('.creator').removeClass('view preview editor');
	$('.creator').addClass(mode);
	Editor.mode = mode;
	Editor.ShowSubMenu('clear');		
	
	var centeralizePage = ($('.creator').height() - 920)/2;
	
	if (mode == 'edit')
	{
		
		$(".canvas-wrapper").css("zoom", "100%")
		
		Editor.active = true; 
		$('.creator .show-only-in-editor' ).show();
		$('#zenbox_tab').show();
		$('.site-page').css({'border': 'solid 1px #CCCCCC'});
		$('.upload-queue').show();
		$('#habla_both_div').show();
			//setTimeout(function() {   if ($.cookie('hint-editor') != '1') Editor.ShowSubMenu('hint-editor');   }, 5000);	
			
			$('#iphone-graphics-container').stop().animate({
				opacity: 0
			}, 800, function() {
			    // Animation complete.
			 });
			
			$('#iphone-overlay').css('z-index', 0);
			$('#qr_code').hide();
			
			
	}
	else if (mode == 'preview')
	{
		Editor.active = false; 
		CurrentPage().DeselectVisualBox(); 
		$('.site-page').css({'border': 'solid 0px #CCCCCC'});
		setTimeout(	function() { $('.creator .show-only-in-editor' ).hide(); }, 1500);
		

		//var myScroll = new iScroll('wrapper2');

		if ( CurrentPage().vbWidth == 480){
			
		   
		   $('#iphone-graphics-container').stop().animate({
				opacity: 1
			}, 800, function() {
			    // Animation complete.
			 });
		   
		   
		   $('#iphone-overlay').css('visibility', 'visible');
			$('#iphone-overlay').css('z-index', 30000);
			VbHelper.centeralizeMobile(1)
			//$(".canvas-wrapper").css("zoom", "85%")
			Viewer.ScrollToPosition(0, true);
			$('#qr_code').attr('src', 'https://chart.googleapis.com/chart?chs=300x300&cht=qr&choe=UTF-8&chl=http://premob.im-creator.appspot.com/view?vbid='+CurrentWebsite().vbId)
			$('#qr_code').show();
		   
		}
		
		console.log("Preview mode Hiding!!!!");
		$('#zenbox_tab').hide();
		$('.upload-queue').hide();
		$('#habla_both_div').hide();
	}		
	else if (mode == 'view')
	{
		Editor.active = false; 
		if (CurrentPage()!=null) CurrentPage().DeselectVisualBox(); 
		$('.site-page').css({'border': 'solid 0px #CCCCCC'});
		setTimeout(	function() { $('.creator .show-only-in-editor' ).hide(); }, 1500);
		console.log("view mode Hiding!!!!");
		$('#zenbox_tab').hide();
		$('.upload-queue').hide();
		$('#habla_both_div').hide();
		if (Editor.modeDemo) 
		{
			setTimeout(function() {   if ($.cookie('hint-demo') != '1') Editor.ShowSubMenu('hint-demo');   }, 5000);
		}
	}	
	
	Editor.ToggleModeFor(mode, CurrentWebsite());	
}



/**
Recursively update all VisualBoxes about a mode change.
@param {String} mode	The current editor mode: 'edit', 'preview', 'view'.
@param {String} vb		Parent visualbox to update, children will be updated too.
*/
Editor.ToggleModeFor = function(mode, vb)
{
	if (vb==null) return;
	vb.OnEditorModeChanged(mode);
	for (var idx in vb.vcChildren)
	{
		var child = vb.vcChildren[idx];
		Editor.ToggleModeFor(mode, child); // Recuse
	}
}



/** 
Toggle debug mode 
*/
Editor.ToggleDebugMode = function()
{
	if (Editor.debugMode) Editor.StopDebugMode();
	else Editor.StartDebugMode();
}


/** 
Start debug mode 
*/
Editor.StartDebugMode = function()
{
		Editor.debugMode = true;
		//$('.debugwindow').show();
		$('.exportwindow').show();
		$('.exportwindow TEXTAREA').unbind('focus').focus(function() { Editor.inXmlArea = true; this.select() });
		$('.exportwindow TEXTAREA').unbind('blur').blur(function() { Editor.inXmlArea = false; });
		Editor.DumpDebugInformation();
}

/** 
Stop debug mode 
*/
Editor.StopDebugMode = function()
{
	Editor.debugMode = false;
	//$('.debugwindow').hide();
	$('.exportwindow').hide();
}

/**
Update the debug textareas with debug information. Call repeatedly.
*/
Editor.DumpDebugInformation = function()
{
	$('.exportwindow TEXTAREA').val('Loading...');
	var xml = CurrentWebsite().Serialize();
	//if (!Editor.inXmlArea)
	{
		$('.exportwindow TEXTAREA').val(xml);
	}
}

Editor.EnableCheckOnClose = function(enable)
{
	if (Editor.mode == 'view' || generateWebsite) enable = false;
	function checkClose()
	{
		Tracking.TrackImEvent("exit_editor/")
		msg = "";
		try
		{
			var isSaved = CurrentWebsite() && CurrentWebsite().IsSaved();
			if (isSaved)
				msg = "";
			else
				msg = "You will lose all your changes!";
		}
		catch (e)
		{
			msg = "You will lose all your changes!";
		}
		var isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
		if (isChrome) 
		{
			msg = "Are you sure you want to close the editor?\n" + msg;
		}
		return msg;

	}
	window.onbeforeunload = enable ? checkClose : null;
}


/**
Initialize the editor in generator mode.
Must be called after all DOM is ready.
*/
Editor.InitializeGenerator = function ()
{
	Editor.mode = mode;
	debug.log('Starting Generator Editor');
	ImageQueue.Start();
	Tracking.TrackImEvent("enter_generator_iframe/")		
}

/**
Initialize the editor.
Must be called after all DOM is ready.
@param {String} mode	The initial editor mode: 'edit', 'preview', 'view'.

*/
Editor.Initialize = function (mode)
{
	var dbg = (window.location.href.indexOf('dbg-init=1') != -1);
	if (mode == 'view demo')
	{
		mode = 'view';
		$(".contextmenu").remove();
		Editor.modeDemo = true;
	}
	Editor.mode = mode;
	
	if (dbg) debug.log("Loading Editor - Phase 1");
	if (window.location.href.indexOf('dbg=1') != -1)
	{
		Editor.StartDebugMode();
	}

	if (dbg) debug.log("Loading Editor - Phase 2");
	Tracking.TrackImEvent("enter_editor/")

	if (dbg) debug.log("Loading Editor - Phase 3");
	if (dbg) debug.log("Loading Editor - Phase 4");
	Editor.EnableCheckOnClose(true);
	Editor.InitializeSpecialKeys();

	// Disable text selection
	if (dbg) debug.log("Loading Editor - Phase 6");
	$(document).disableTextSelect();
	$('.visualbox-frame .toolbar').disableTextSelect();

	// Disable browser right-click context menu
	if (Editor.mode == 'edit')
	{
		$(document).bind("contextmenu", function (e) { return false; });
	}


	// Initialize Window
	if (dbg) debug.log("Loading Editor - Phase 7");
	$(window).resize(function () { VbHelper.OnWindowResize(); });
	VbHelper.OnWindowResize();

	// Initialize the "Add Element" submenu
	if (dbg) debug.log("Loading Editor - Phase 8");
	Editor.InitializeAddElement();

	// Initialize SwfUpload
	if (dbg) debug.log("Loading Editor - Phase 9");
	if (Editor.mode != 'view') Uploader.HideButton();
	if (Editor.mode != 'view') Uploader.Initialize();


	// Initialize TinyMCE
	if (dbg) debug.log("Loading Editor - Phase 10");
	if (Editor.mode != 'view') TinyMceHelper.InitializeTinyMce();

	// Make sure menu shadow does not cover vertical scrollbar
	if (dbg) debug.log("Loading Editor - Phase 11");
	var w1 = $('.creator').innerWidth();
	var w2 = $('.creator .canvas').innerWidth();
	var scrollbarWidth = w1 - w2;
	$('.creator .canvas-wrapper .shadow').css('right', scrollbarWidth + 'px');

	if (dbg) debug.log("Loading Editor - Phase 12");
	ImageQueue.Start();
	
	
	if (mode == 'edit' && $.browser.msie)
	{
		// IE triggers window.onbeforeunload on every href="javascript:...", 
		// therefore triggering the "Are you sure?" dialog upon every button press in the Editor
		// Let's avoid it by replacing all href="javascript:void()" with href="#"
		$('a').filter(function() {
	        return (/^javascript\:void/i).test($(this).attr('href'));
	    }).attr('href', '#');
	}
	
	if (dbg) debug.log("Loading Editor - Done");
}


/**
Determines whether an input field is currently focused
@returns {Boolean} true if an input field is focused; otherwise, false
*/
Editor.IsInputFieldFocused = function()
{
	if (this.active == true) return false; // Always return false in editor mode
	if ( $('input:focus').length>0 ) return true;
	if ( $('textarea:focus').length > 0 ) return true;
	return false;
}

/**
Initialize the special keywords for the editor
*/
Editor.InitializeSpecialKeys = function ()
{
	$(window).keydown(function (e)
	{
		//debug.log("Keydown: ", e.which);
		if (e.ctrlKey && e.which == 65) // Ctrl+A
		{
			if (Editor.isInEditMode)
			{
				TinyMceHelper.SelectAllText(); // select all text inside TinyMCE editor
			}
			return false;
		}

		if (e.ctrlKey && e.which == 76)  // Ctrl+L
		{
			CurrentDevice().ReplicateMarkedElements();
			return false;
		}

		if (e.ctrlKey && e.which == 83)  // Ctrl+S
		{
			CurrentWebsite().SaveToServer();
			return false;
		}

		// Don't run the following shortcut in text-editing more or inside dialogs
		if (Editor.IsInPageMode())
		{
			var focusedElement = $(document.activeElement);
			var olark = focusedElement.parents('.olrk-state-expanded');
			if (olark.length > 0) // focused on a olark input box
				return true; // don't do anything, let the normal event run
			
			if ((e.ctrlKey || e.metaKey) && e.which == 67) CurrentPage().CopyMarkedElementsToClipboard(); // Ctrl+C
			if ((e.ctrlKey || e.metaKey) && e.which == 88) CurrentPage().CutMarkedElementsToClipboard(); // Ctrl+X
			if ((e.ctrlKey || e.metaKey) && e.which == 86) CurrentPage().PasteFromClipboardToPage(true); // Ctrl+V

			if (e.keyCode == 8 && !Editor.IsInputFieldFocused()) return false; // Disable backspace navigating to the previous page of the browser
			if (e.which == 46 && !Editor.IsInputFieldFocused()) CurrentPage().DeleteMarkedElements(); // Del

			if (e.ctrlKey && e.which == 81) // Ctrl+Q for debug
			{
				Editor.ToggleDebugMode();
			}

			if (e.which == 39 && !Editor.IsInputFieldFocused()) // right arrow
			{
				e.preventDefault();
				var markedChildren = CurrentPage().GetMarkedChildren();
				for (idx in markedChildren)
				{
					var vb = markedChildren[idx];
					var frame = $('#vbx-' + vb.vbId);
					vb.vbX += 1;
					vb.contentElement.css('left', vb.vbX);
					vb.OnDragStopped(frame);
				}
				VbHelper.OnWindowResize(true);
			}

			if (e.which == 37 && !Editor.IsInputFieldFocused()) // left arrow
			{
				e.preventDefault();
				var markedChildren = CurrentPage().GetMarkedChildren();
				for (idx in markedChildren)
				{
					var vb = markedChildren[idx];
					var frame = $('#vbx-' + vb.vbId);
					vb.vbX -= 1;
					vb.contentElement.css('left', vb.vbX);
					vb.OnDragStopped(frame);
				}
				VbHelper.OnWindowResize(true);
			}

			if (e.which == 38 && !Editor.IsInputFieldFocused()) // up arrow
			{
				e.preventDefault();
				var markedChildren = CurrentPage().GetMarkedChildren();
				for (idx in markedChildren)
				{
					var vb = markedChildren[idx];
					var frame = $('#vbx-' + vb.vbId);
					vb.vbY -= 1;
					vb.contentElement.css('top', vb.vbY);
					vb.OnDragStopped(frame);
				}
				VbHelper.OnWindowResize(true);
			}

			if (e.which == 40 && !Editor.IsInputFieldFocused()) // down arrow
			{
				e.preventDefault();
				var markedChildren = CurrentPage().GetMarkedChildren();
				for (idx in markedChildren)
				{
					var vb = markedChildren[idx];
					var frame = $('#vbx-' + vb.vbId);
					vb.vbY += 1;
					vb.contentElement.css('top', vb.vbY);
					vb.OnDragStopped(frame);
				}
				VbHelper.OnWindowResize(true);
			}
		}
	});
}




Editor.MoveAllMarkedContentAndFrames = function(event, ui, draggedVbFrame, markedChildren, stop)
{
	for (idx in markedChildren)
	{
		var vb = markedChildren[idx];
		var vbFrame = $('#vbx-'+vb.vbId);
		if (stop)
			allow = vb.OnDragStopped(vbFrame, true);
		else	
			allow = vb.OnDrag(vbFrame);
		if (allow)
		{
			if (stop)
				vbFrame.show();
			else
				vbFrame.hide();
			VbHelper.OnFrameResizeOrMove(draggedVbFrame, vbFrame, event, ui);
		}
	}
}

/**
Initializes the VisualBox selection frame.
*/
Editor.InitializeSelectionFrame = function (frame, markedChildren)
{
	if (markedChildren.length > 1)
	{
		$('.visualbox-frame').addClass('multiple');
	}
	else
	{
		$('.visualbox-frame').removeClass('multiple');
	}

	$('.visualbox-frame').resizable('destroy');

	if (markedChildren.length <= 1)
	{
		// Initialize selection frame - make it resizable and draggable
		frame.resizable(
		{
			containment: false,
			handles: 'se,sw,ne,nw',
			grid: [1, 1], // [50, 1]
			
			resize: function (event, ui)
			{
				CurrentPage().GetSelectedChild().OnTopLeftCornerDrag($(this));
				VbHelper.OnFrameResizeOrMove($(this), $(this), event, ui);
				VbHelper.ChangeFrameContainment($(this));
			},
			stop: function (event, ui)
			{
				CurrentPage().GetSelectedChild().OnDragStopped($(this), false);
				VbHelper.OnFrameResizeOrMove($(this), $(this), event, ui);  // The final few pixels when stopping resize
				Editor.isDraggingOrResizingNow = false;
			},

			start: function (event, ui)
			{
				CurrentPage().GetSelectedChild().OnDragStarted($(this));
				Editor.isDraggingOrResizingNow = true;
			}
		});
	}

	
	frame.draggable(
	{
		containment: '.canvas',
		scroll: false,
		cancel: '.toolbar',
		handle: '.visualbox-frame .drag-corner',
		cursor: 'move',
		//snap: ".visualbox-content, #iphone-left",
		//snapTolerance: 8,
		
		distance: 5, /* to avoid double click accidentally dragging the element */
		drag: function (event, ui)
		{
			Editor.MoveAllMarkedContentAndFrames(event, ui, $(this), markedChildren, false)
		},
		stop: function (event, ui)
		{
			Viewer.TogglePicturesInfo(true);
			Editor.MoveAllMarkedContentAndFrames(event, ui, $(this), markedChildren, true)
			Editor.isDraggingOrResizingNow = false;
			Editor.dragOffsetsByVbid = Array()
		},

		start: function (event, ui)
		{
			Editor.isDraggingOrResizingNow = true;

			// Calculate and save offset of all marked elements from the dragged element
			Editor.dragOffsetsByVbid = Array()
			var draggedVbVbid = VbHelper.GetVbidFromElement($(this));
			var draggedVbContent = $('#vbc-' + draggedVbVbid);
			for (idx in markedChildren)
			{
				var vb = markedChildren[idx];
				vb.OnDragStarted($(this));
				var currentVbContent = vb.contentElement;
				var vbTop = parseInt(currentVbContent.css('top').replace('px', ''));
				var dgTop = parseInt(draggedVbContent.css('top').replace('px', ''));
				var vbLeft = parseInt(currentVbContent.css('left').replace('px', ''));
				var dgLeft = parseInt(draggedVbContent.css('left').replace('px', ''));
				var xOffset = vbLeft - dgLeft;
				var yOffset = vbTop - dgTop;
				Editor.dragOffsetsByVbid[vb.vbId] = Array(xOffset, yOffset);
			}

		}
		
		
		
		
	});

	// Allow unselecting elements
	frame.mousedown(function (event, ui)
	{
		if (event.which == 1) // Left mouse click
		{
			if (event.shiftKey || event.ctrlKey)
			{
				var vbid = event.target.id.substring(4);
				var vb = CurrentPage().GetChildObjectByVbid(vbid);
				CurrentPage().UnmarkVisualBox(vb);
			}
			ContextMenu.Hide();
		}
		else if (event.which == 3) // Right mouse click
		{
			ContextMenu.ShowForMarkedElements(event);
		}
	});

	frame.mouseup(function (event, ui)
	{
		var vbid = event.target.id.substring(4);
		var contentElement = $('#vbc-' + vbid);

		// Click through frame to element
		buttons = Array(".paginator .prev-button", ".paginator .next-button", ".paginator .page-button", ".input-wrapper", ".website-menu-item");
		for (var buttonIndex in buttons)
		{
			var button = buttons[buttonIndex];
			var items = contentElement.find(button);
			if (items.size() > 0)
			{
				items.each(function (index, element)
				{
					var item = items.eq(index);
					var offset = item.offset();

					var x1 = offset.left;
					var x2 = offset.left + item.outerWidth(false);
					var y1 = offset.top;
					var y2 = offset.top + item.outerHeight(false);

					if (event.pageX >= x1 && event.pageX <= x2 && event.pageY >= y1 && event.pageY <= y2)
					{
						//debug.log("Click through to element", button, ":", item);
						item.trigger('click');
					}
				});
			}
		}
	});


	// Set the correct dragging-containment for the VB-frame
	$("#visualboxes-frames").children().each(function ()
	{
		VbHelper.ChangeFrameContainment($(this));
	});


	// Workaround to enable selecting an overlapping VisualBox while the frame focuses on another VisualBox.
	// Without this workaround, the frame would mask the VisualBox, thus not allowing the click event to propogate.
	frame.mouseup(function (e)
	{

		var maxZ = 0;
		var elementToSelect = null;
		var mouseX = e.pageX;
		var mouseY = e.pageY;

		// Find the frame's location
		var offset = $(this).offset();
		var width = $(this).width();
		var height = $(this).height();

		// Don't handle clicks on toolbar or border, only inside frame rectnagle
		var insideFrameRectangle = (mouseX > offset.left && mouseX < offset.left + width && mouseY > offset.top && mouseY < offset.top + height);
		if (!insideFrameRectangle)
			return;

		$(".visualbox-content-instance").each(function ()
		{
			var contentVbid = VbHelper.GetVbidFromElement($(this));

			// Find the content's location and z-order
			var offset = $(this).offset();
			var width = $(this).width();
			var height = $(this).height();
			var zIndex = parseInt($(this).css('z-index'));

			// If content is inside frame AND it's the heighest content so far AND we're not currently dragging or moving the VisualBox
			if (mouseX > offset.left && mouseX < offset.left + width &&
					mouseY > offset.top && mouseY < offset.top + height &&
					zIndex >= maxZ && Editor.isDraggingOrResizingNow == false)
			{
				elementToSelect = $(this);
				maxZ = zIndex;
			}
		});

		if (elementToSelect)
		{
			var selectedFrame = $(this);
			var isAlreadySelected = (VbHelper.GetVbidFromElement(elementToSelect) == VbHelper.GetVbidFromElement(selectedFrame));
			if (!isAlreadySelected)
			{
				elementToSelect.mousedown(); // Force the click event
			}
		}
	});



	// Allow deselection of frame
	$('.canvas').mousedown(function (event)
	{
		if (CurrentPage()) CurrentPage().DeselectVisualBox(); event.stopPropagation()
		ContextMenu.Hide();
	});

	// Don't propogate mousedown to page/canvas, otherwise it will deselect the frame upon click
	frame.mousedown(function (e)
	{
		e.stopPropagation();
	});

	// Wire frame buttons
	frame.find('.toolbar .btn.delete').click(function ()
	{
		var vbid = VbHelper.GetVbidFromElement($(this).parentsUntil('.visualbox-frame').parent());
		CurrentPage().DeleteChildElement(vbid);
	});
	frame.find('.toolbar .btn.moveup').click(function ()
	{
		var vbid = VbHelper.GetVbidFromElement($(this).parentsUntil('.visualbox-frame').parent());
		CurrentPage().MoveElementUp(vbid);
	});
	frame.find('.toolbar .btn.movedown').click(function ()
	{
		var vbid = VbHelper.GetVbidFromElement($(this).parentsUntil('.visualbox-frame').parent());
		CurrentPage().MoveElementDown(vbid);
	});

	frame.find('.toolbar .btn.link').click(function ()
	{
		var vbid = VbHelper.GetVbidFromElement($(this).parentsUntil('.visualbox-frame').parent());
		var vb = CurrentPage().GetChildObjectByVbid(vbid);
		Dialogs.OpenInfoDialog(vb, true, function (obj) { vb.vmLink = obj.vmLink; vb.OnInfoChanged(); });
	});
}



/**
Initialize the "Add Element" submenu
*/
Editor.InitializeAddElement = function ()
{
	$('.creator > .submenu, .creator > .menu').click(function ()
	{
			ContextMenu.Hide();
	});

	$('.creator .submenu .elements .add-element').click(function ()
	{
		var domId = $(this).attr('id');
		var vmClass = domId.substring(4);
		CurrentPage().AddChildElement(vmClass, null, null)
	});
	
	//testt add an elment from 'preset' list
	$('.creator .submenu .elements .add-element-list').click(function ()
			{
				var domId = $(this).attr('id');
				var vmClass = domId.substring(4);
				Editor.ShowPresets(WidgetBoxElementsPresets, 'Widgets')
				//CurrentPage().AddChildElement(vmClass, null, null)
			});

	$('.creator .submenu .elements .add-element').draggable(
			{
				scroll: true,
				helper: 'clone',
				opacity: 0.7,
				
				drag: function (event, ui)
				{

					
					var contentParentOffset = CurrentPage().contentElement.offset();
					var iconsParentOffset = $(".creator .submenu .elements").offset();
					var y = ui.position.top - contentParentOffset.top + iconsParentOffset.top;

					CurrentPage().MakeSpace(y , 300 , false);
					
				},
				
				stop: function (event, ui)
				{
					var domId = $(this).attr('id');
					var vmClass = domId.substring(4);
					var contentParentOffset = CurrentPage().contentElement.offset();
					var iconsParentOffset = $(".creator .submenu .elements").offset();
					var y = ui.position.top - contentParentOffset.top + iconsParentOffset.top;
					var x = ui.position.left - contentParentOffset.left + iconsParentOffset.left;
					var xChange = Math.abs(ui.position.top - ui.originalPosition.top);
					var yChange = Math.abs(ui.position.left - ui.originalPosition.left);

					// It's a accidental drag, just put it in a random location
					if (xChange < 20 && yChange < 20) x = y = null;

					// Put constaints
					var maxX = $(".page").width();
					var maxY = $(".page").height();
					if (x < 0) x = 20;
					if (y < 0) y = 20;
					if (x > maxX) x = maxX - 20;
					if (y > maxY) y = maxY - 20;
				
				
					CurrentPage().AddChildElement(vmClass, x, y);
					CurrentPage().MakeSpace(y , 300 , true);
					
					
					
				}
			});
	
	
}


//===================================== CLIPBOARD ======================================//

/**
Gets the content of the clipboard
@returns	{Object}	The contents of the clipboard.
*/
Editor.GetClipboard = function()
{
	
		time_from_cookie =  $.cookie('clipboard_time')
		console.log("this is the time from cookie: ", Number(time_from_cookie));
		console.log("this is the time from editor: ", Number(Editor.clipboard_time));
		
		if (!time_from_cookie || (Number(time_from_cookie) <= Editor.clipboard_time)){
			//console.log("got it from teh Editor itself!", Editor.clipboard);
			
			clipboard = unescape(Editor.clipboard);
			clipboard = clipboard.replace("<ImClipboard>", "");
			clipboard = clipboard.replace("</ImClipboard>", "");
			
			
			return clipboard;
			
		} else {
			
			console.log("got it from teh cookie");
				num_of_cookies = $.cookie('clipboard_parts')
				
				if (num_of_cookies >= 6){
					
					clipboard = unescape(Editor.clipboard);
					clipboard = clipboard.replace("<ImClipboard>", "");
					clipboard = clipboard.replace("</ImClipboard>", "");
					return clipboard;
					
				} else {
		
				obj = ""
				for (i=0;i<=num_of_cookies;i++)
				{
					cookie_name = "im_clipboard"+i
					obj = obj+$.cookie(cookie_name)
				}
				
				clipboard = unescape(obj);
				clipboard = clipboard.replace("<ImClipboard>", "");
				clipboard = clipboard.replace("</ImClipboard>", "");
				return clipboard;
			
		}
	
	
	
	}
}

/**
Puts the specified object in the clipboard.
@param	{Object}	obj		Any kind of object to put in the clipboard.
*/
Editor.SetClipboard = function(obj)
{
	    obj = "<ImClipboard>" + obj + "</ImClipboard>";
	    obj = escape(obj);    

		num_of_cookies = Math.ceil(obj.length / 2000)
		
		var now = new Date();
		var now_number = Number(String(now.getYear())+ String(now.getMonth())+ String(now.getDay())+ String(now.getHours())+ String(now.getMinutes()));
			
		console.log(now_number);
		
		
		$.cookie("clipboard_parts", num_of_cookies, { path: '/' }); 
		$.cookie("clipboard_time", now_number, { path: '/' }); 
		
		Editor.clipboard_time = now_number;
		Editor.clipboard = obj
		
		
		if (num_of_cookies >= 6){
			
			console.log("too many object, using local clipboard only")
			
		} else {
			
			for (i=0;i<=num_of_cookies;i++)
			{
				cookie_name = "im_clipboard"+i
				cookie_content = obj.slice(i*2000, (i+1)*2000)
				$.cookie(cookie_name, cookie_content, { path: '/' }); 
			}
			
		}
		
		
	
	//	debug.log("Clipboard set to: ", obj);
	
	//alert(escape(Editor.clipboard).length)
	
	//Editor.clipboard = obj;
	//localStorage.setItem('testObject', obj);
	//$.cookie('im_clipboard', obj, { path: '/' });
}


Editor.UpdateClones = function ()
{
	//console.log("UpdateClones", Editor.pendingClones);
	var elementToClone = Editor.pendingClones;
	if (Editor.pendingClones.length == 0) return;
	
	// Remove duplicate VisualBoxes from list
	var pendingClonesByVbid = Array();
	for (idx in Editor.pendingClones)
	{
		var vb = Editor.pendingClones[idx];
		pendingClonesByVbid[vb.vbId] = vb;
	}
	var uniqueElementsToClone = Array();
	for (idx in pendingClonesByVbid)
	{
		var vb = pendingClonesByVbid[idx];
		uniqueElementsToClone.push(vb);
	}

	CurrentDevice().ReplicateElements(uniqueElementsToClone, false);
	Editor.pendingClones = Array();

}

//===================================== MISC FUNCTIONS ======================================//


/**
A function to determine whether the user is currently watching the page, as opposed to
editing an element or watching a dialog.
@returns	{Boolean}	'true' if the user is watching a page, otherwise 'false'
*/
Editor.IsInPageMode = function()
{
	var pageMode = (!Editor.isShowingDialog && !Editor.isInEditMode);
	return pageMode;
}



/**
Shows the specified submenu onscreen, instead of the old submenu.
@param	{String}	menuName	The name of the submenu to show (usually a vmClass name)
@param	{String}	vbid		The VisualBox ID of the selected element which belongs to this submenu. May be null!
*/ 
Editor.ShowSubMenu = function(menuName, vbid)
{
	if (Editor.mode=='view' && !Editor.modeDemo) return;
	
	var isHintSubMenu = (menuName.indexOf('hint-') == 0);

	if (menuName != Editor.currentSubMenu && menuName != 'slideup')
	{
		Editor.HideAllDropDownMenus();
	}
	var prevSubMenu = Editor.currentSubMenu;
	Editor.previousSubMenu = prevSubMenu;
	Editor.currentSubMenu = menuName;
	if (Editor.mode!='view') Uploader.HideButton();
	$('.creator .replace-pic-wrapper').show();
	if (menuName == 'elements-menu')
	{
		$('.creator .submenu').show();
		$('.creator .submenu').animate({opacity: 1, height: '100'}, 350);
		$('.creator .submenu .submenu-content').fadeOut(0);
		$('.creator .submenu .submenu-content.' + menuName).fadeIn(200);
		$('.creator .submenu .shadow').show();
		$('.creator .submenu .shadow').animate({top: '160',opacity: 1}, 350);
	}
	else if (menuName == 'PresetsMenu')
	{
		$('.creator .submenu').show();
		$('.creator .submenu').animate({opacity: 1, height: '130'}, 350);
		$('.creator .submenu .submenu-content').fadeOut(0);
		$('.creator .submenu .submenu-content.' + menuName).fadeIn(200);
		$('.creator .submenu .shadow').show();
		$('.creator .submenu .shadow').animate({top: '190',opacity: 1}, 350);
	}
	else if (menuName == 'clear')
	{
		$('.creator .submenu .shadow').hide();
		$('.creator .submenu').hide();
		$('.creator .submenu .shadow').css('top', '0');
		$('.creator .submenu .shadow').css('opacity', '0');
		$('.creator .submenu').css('height', '0');
	}
	else if (menuName == 'slideup')
	{
		var length = 1000;
		$('.creator .submenu').animate({opacity: 0, height: '0'}, length);
		$('.creator .submenu .shadow').animate({top: '60px',opacity: 0}, length).delay(length);
		$('.creator .submenu .submenu-content.' + prevSubMenu).fadeOut(length);
	}
	else // All elements submenus
	{
		var length = isHintSubMenu ? 1000 : 350;
		$('.creator .submenu').show();
		$('.creator .submenu').animate({opacity: 1, height: '70'}, length);
		$('.creator .submenu .shadow').show().animate({top: '130',opacity: 1}, length);
		$('.creator .submenu .submenu-content').hide();
		if (menuName == 'ParagraphBox' || menuName == 'TitleBox')
		{
			$('.creator .submenu .submenu-content.ParagraphBox .paragraph-type').css('display', (menuName=='ParagraphBox'?'block':'none'));
			$('.creator .submenu .submenu-content.ParagraphBox .title-type').css('display', (menuName=='ParagraphBox'?'none':'block'));
			menuName = 'ParagraphBox';
		}
		//length = Math.round(length * 20 / 35);
		$('.creator .submenu .submenu-content.' + menuName).fadeIn(length);
    	if (menuName == 'settings-menu')
    	{
			if (Editor.mode!='view') Uploader.ShowButton($('.creator .submenu .settings-menu .favicon'), 'REPLACE-FAVICON');			
    	}
    		
		if (menuName == 'PictureBox') 
		{
			if (Editor.mode!='view') Uploader.ShowButton($('.creator .submenu .submenu-content .replace-pic-button'));			
			
			// When mouse is over flash button - highlight below the flash upload button
			$('.creator .submenu .submenu-content .convert').mouseenter(function(event)
			{
				 $('.creator .submenu .submenu-content .convert').css('background', '#000000');
				 $(this).css('background', '#202020');
				 var action = null;
				 if ($(this).hasClass('convert-to-gallery'))   action='CONVERT-TO-GALLERY';
				 if ($(this).hasClass('convert-to-slideshow')) action='CONVERT-TO-SLIDESHOW';
				 if (Editor.mode!='view') Uploader.ShowButton($(this), action);
				 event.stopPropagation()
			});
			// When mouse is not over button - remove highlights, and restore flash button to "Add Pic"
			$('.creator .submenu .submenu-content .dropdownmenu').mouseenter(function(event)
			{
				 $('.creator .submenu .submenu-content .convert').css('background', '#000000');
				 if (Editor.mode!='view') Uploader.ShowButton($('.creator .submenu .submenu-content .replace-pic-button'), null);
			});

		}
		if (Editor.mode!='view') 
		{
    		if (menuName == 'SlideShowBox' || menuName == 'GalleryBox') Uploader.ShowButton($('.creator .submenu .submenu-content.'+menuName+' .add-pic-button'), null);
		}
	 }

	 if (isHintSubMenu)
	 {
		$.cookie(menuName, '1');
	 }
}

/**
Toggles the specified dropdown menu onscreen.
@param	{jQuery Object}	menu	The jQuery object of the menu. e.g. $('#someMenu')
*/ 
Editor.ToggleDropDownMenu = function(menu)
{
	var dd = menu.find('.dropdownmenu');
	var lnk = menu.find('.dropdownlink');
	dd.stop();
	dd.css('height', 'auto');
	if (dd.css('display')=='none')
	{
		dd.fadeIn();
		//lnk.find('IMG').attr('src', '../images/submenu/operations/up-arrow.png');
	}
	else
	{
		dd.fadeOut();
		//lnk.find('IMG').attr('src', '../images/submenu/operations/down-arrow.png');
	}
}

/**
Hides all the dropdown menus.
@param	{jQuery Object}	menu	The jQuery object of the menu. e.g. $('#someMenu')
*/ 
Editor.HideAllDropDownMenus = function()
{
	$('.dropdownmenu').hide();
	$('.dropdownlink IMG').attr('src', '../images/submenu/operations/down-arrow.png');
}



/**
Debug mode: Read the XML in the textarea and deserialize it into the website.
*/
Editor.DeserializeFromTextarea = function()
{
	var xml = $('.exportwindow textarea').val();
	currentWebsite = ImSerializer.Deserialize(xml, true, CurrentPage());
	console.log(currentWebsite);
}

Editor.LoadWebsiteFromUrl = function(url)
{
	$('.creator .canvas .website > .child-container').children().remove();
	$.get('extra_pages/default-website.txt', function(xml)
	{
		Editor.LoadWebsiteFromXml(xml)
	});
}

Editor.LoadWebsiteFromXml = function(xml)
{
	var parentVisualBox = null;
	Editor.active = (Editor.mode == 'edit');
	currentWebsite = ImSerializer.Deserialize(xml, true, parentVisualBox);
	// This will be called for 1st page view only
    if (ImSerializer.pageIndexDeserialized == null) ImSerializer.pageIndexDeserialized = 0;
	var selectedPage = CurrentDevice().vcChildren[ImSerializer.pageIndexDeserialized];
	Viewer.OnPageViewed(selectedPage);
	Editor.ToggleMode(Editor.mode);
	// When loading a template, always load the 'save as' dialog
	if (isTemplate) CurrentWebsite().isSaved = false;

	
	if (generateWebsite)
	{	
		Editor.GenerateWebsite();
	}
	
	if (jQuery.url.param("domain"))
	{
		PublishDialogs.OnPublishButtonClicked();
	}
	
	if (paymentStatus=='success') // After PayPal payment
	{
		Tracking.TrackImEvent("paid_back_to_editor/")
		PublishDialogs.OpenChooseDomainDialog();
	}
	
	if (paymentStatus=='success_domain') // After PayPal payment
	{
		Tracking.TrackImEvent("paid_for_domain_back_to_editor/")
		PublishDialogs.AfterNewDomainPurchased();
	}
	

	// Create SEO Juice
	if (window.location.href.indexOf('show-seo=1') != -1)
	{
		var seoJuice = ImJuicer.CreateSeoJuiceForWebsite();
		document.write("<textarea style='width:100%;height:100%'>" + seoJuice + "</textarea>");
		//debug.log(seoJuice);
	}
	
	if (window.location.href.indexOf('show-sitemap=1') != -1)
	{
		var sitemapJuice = ImJuicer.CreateSitemapJuice();
	}
	
	

	
	//Facebook post-generating options
		
	
	
	
	
	var showButtons = 
		(domain != "true") && 
		(mode == 'view') && 
		(CurrentWebsite().vmOrigin == "FacebookWebsiteGenerator") &&
		$.cookie('generated_'+CurrentWebsite().vbId) == '1'
		;
	
	
	
	//Watermarks
	
	if((domain != "true") && (mode == 'view') && (showButtons == false)) {
		
		
		
		
		if (window.top != window){
			
			console.log("we're inside an iframe!");
			if ((premium == "false") && ( CurrentWebsite().vbWidth > 500 )){

				
				
				console.log("and user didn't pay")
				$('#watermark').attr("src", "/images/whatsNext/iframe_bear.png")

			} else {
				console.log("nice user!")
			}
			
		} else {
			
			console.log("we're NOT inside an iframe!");
		}
		
		
		if ((premium != "true")) {
		
			$('.watermark').css('display', 'inline')
			$('.watermark').delay(5000).animate({
			    opacity: '1'
			  }, 2000, function() {
			    // Animation complete.
			  });
		}
		
	}
	
	//facebook
	
	
		if (showButtons) {
	   	     Tracking.TrackEvent('im', 'fb_gen/website_viewed');
			
			var suggestedDomain = $.get(
        		    Configuration.GetCheckDomainNamePath(),
        		    {vbid: CurrentWebsite().vbId},
        		    function(data){
        		        console.log("Your domain is: " + data);
        		        $("#domainText").html("Good News! "+data+" is available - <a href='javascript:void(0);' id='publishLink'>connect your new site to a domain</a> or <a href='javascript:void(0);' id='customizeLink'>keep customizing it</a>:");
        		        Editor.WireCustomizeButtons();
        		      });
			
			
			$('#whatsNextStrip').css('display', 'inline')
			
			$('#whatsNextStrip').delay(6000).animate({
				height: '50',
				opacity: 1
			 }, 2000, function() {
			    // Animation complete.
			  });
			
			$('#whatsNextSpace').delay(6000).animate({
			    height: '50'
			 }, 2000, function() {
			    // Animation complete.
			  });
			
			$('#whatsNextShadow').delay(6000).animate({
			    top: '50',
			    opacity: 1
			 }, 2000, function() {
			    // Animation complete.
			  });
		  
		  
		  Editor.WireCustomizeButtons();
		  $("#closeBtn").click(function() {
			  
				$('#whatsNextStrip').animate({
					height: '0',
					opacity: 0
				 }, 2000, function() {
				    // Animation complete.
				  });
				
				$('#whatsNextSpace').animate({
				    height: '0'
				 }, 2000, function() {
				    // Animation complete.
				  });
				
				$('#whatsNextShadow').animate({
				    top: '0',
				    opacity: 0
				 }, 2000, function() {
				    // Animation complete.
				  });
			  
			  
		  });		
		
		}		  
	/*var selectedPage = CurrentPage();
	var scale = parseInt(10000.0 * window.innerWidth / selectedPage.vbWidth) / 10000.0;
	document.getElementById("viewport").setAttribute('content', 'width=' + selectedPage.vbWidth + ', height=' + selectedPage.vbHeight + ', initial-scale=' + scale + ', maximum-scale=10, minimum-scale=0.1');*/

}

Editor.WireCustomizeButtons = function()
{
	  
	  $("#customizeBtn, #customizeLink").unbind('click').click(function() {
		 $.cookie('generated_'+CurrentWebsite().vbId, '2');
   	     Tracking.TrackEvent('im', 'fb_gen/customize_website_clicked');
	     window.location = Configuration.GetEditorPathToLoadVbid(CurrentWebsite().vbId);
	  });
	  $("#publishBtn, #publishLink").unbind('click').click(function() {
		  $.cookie('generated_'+CurrentWebsite().vbId, '3');
	   	  Tracking.TrackEvent('im', 'fb_gen/connect_website_clicked');
		  window.location = Configuration.GetEditorPathToLoadVbid(CurrentWebsite().vbId)+'&domain=1';
	  });
}


/**
Downscale the text in the specified WebsiteMenuBox to fit the box.
@param	{VisualBox}	vb		The WebsiteMenuBox to downscale.
*/
Editor.DownscaleTextMenu = function(vb)
{
	// Settings
	var MinimalFontSize = 6;
	var MaximalFontSize = vb.vbFontMaxSize;

	// Wrap the textarea with an inner-span to measure the text real width
	var textArea = $('#txa-' + vb.vbId);
	textArea.wrapInner('<span style="float:left;position:absolute" id="textAreaInner"  class="textAreaInner" />');
	if (textArea.find('.textAreaWrapper').size() == 0)
		textArea.wrapInner('<span class="textAreaWrapper"/>');
	var textAreaInner = $('.textAreaInner');

	for (size = MaximalFontSize; size--; size >= MinimalFontSize)
	{
		$('#txa-' + vb.vbId).css("font-size", size + 'pt');
		
		
		var textWidth = textAreaInner.width();
		var vbWidth = vb.innerWidth;
		if (vbWidth >= textWidth)
		{
			//debug.log(vbWidth, textWidth, size);
			
			vb.fontSizeTempHolder = $('#txa-' + vb.vbId).css("font-size");
			
			break; // Font is small enough to fit into box, quit
		}
	}

	// Remove the inner-span
	$(".textAreaInner").replaceWith($(".textAreaInner").html());

}



Editor.ShowPresets = function(presets, title)
{
	Editor.ShowSubMenu('PresetsMenu');
	$('.PresetsMenu .jcarousel-wrapper').html('<ul class="jcarousel-skin-tango carousel"></ul>');
	var elementToApply = CurrentPage().GetSelectedChild();
	
	// Temp duplication
	for (var i=0; i<1; i++)
	for (var idx in presets)
	{
		var preset = presets[idx];
		var id = 'preset-'+idx;
		var li = '<li id="'+id+'"><img class="thumbnail" src="../images/presets/'+preset.Thumbnail+'" alt="" /><span class="name">'+preset.Name+'</span></li>';
		$('.PresetsMenu .jcarousel-wrapper .carousel').append(li);
		$('.PresetsMenu .jcarousel-wrapper .carousel #'+id).unbind('click').click(
					function() 
					{ 
						var i=$(this).attr('id').replace('preset-',''); 
						
						if (presets[i].CallbackFunc){
							CurrentPage().AddWidgetElement(presets[i].CallbackFunc, null, null, presets[i].Source)
						
						} else {
							
							if (presets[i].Background){

									if (mode == 'edit')
									{
										var websiteElement = $('.creator > .canvas-wrapper > .canvas, .creator > .canvas-wrapper, html');
									}
									else
									{
										var websiteElement = $('.creator > .canvas-wrapper, html');
									}
									
									CurrentDevice().vbBackgroundType = 'Picture';
									CurrentDevice().vbBackgroundColor = presets[i].BackgroundColor;
									//vbBackgroundPositionX: 'left',
									//vbBackgroundPositionY: 'top',
									CurrentDevice().vbBackgroundRepeat = presets[i].BackgroundRepeat;
									CurrentDevice().vbBackgroundAttachment = presets[i].BackgroundAttachment;
									CurrentDevice().vbBackgroundImage = presets[i].Background;
									
									
									websiteElement.css('background-color', CurrentDevice().vbBackgroundColor);
									websiteElement.css('background-repeat', CurrentDevice().vbBackgroundRepeat);
									websiteElement.css('background-attachment', CurrentDevice().vbBackgroundAttachment);
									//websiteElement.css('background-position', this.vbBackgroundPositionX + ' ' + this.vbBackgroundPositionY);
									//if (CurrentDevice().vbBackgroundType == 'Picture'){
			 						websiteElement.css('background-image', "url('" + presets[i].Background + "')");
			 						//} else {
									//	alert('outside the css');
									//	websiteElement.css('background-image', "none");
									//};
										
								
							} else {
								
								if (presets[i].Area){
									CurrentDevice().GetSelectedChild().GetSelectedChild().vbBackgroundImageUrl = presets[i].Area;
									CurrentDevice().GetSelectedChild().GetSelectedChild().RenderBoxSettings(CurrentDevice().GetSelectedChild().GetSelectedChild());
								}
								
								elementToApply.LoadAndApplyPreset(presets[i]); 
								
							}
							
						}
					}
				);
		
	}
	$('.PresetsMenu .jcarousel-wrapper .carousel').jcarousel().disableSelection();	
	$('.PresetsMenu').disableSelection();
	$('.PresetsMenu .nav .title').text(title);
	$('.PresetsMenu .nav .back').unbind('click').click(function() { Editor.ShowSubMenu(Editor.previousSubMenu) });
}




//===================================== WEBSITE GENERATOR - GENERATE ======================================//


Editor.GenerateWebsite = function()
{
	console.log('xxxxxxxxxxxxxxx');
	Tracking.TrackEvent('im', 'fb_gen/generating_website');
	CurrentWebsite().vmTitle = Generator.GetPosessiveString(Generator.GetParam('owner_name')) + ' Website';
	CurrentWebsite().vmDescription = Generator.GetParam('owner_headline');
	CurrentWebsite().vbFaviconUrl = Generator.GetParam('owner_picture_square');
	CurrentWebsite().vmOrigin = 'FacebookWebsiteGenerator';
		
	Editor.FillPlaceholders();

	
	// Get picture placeholders
	var pictureBoxes = Array();
	Editor.FindPlaceholderPictureBoxes(CurrentWebsite(), pictureBoxes);
	console.log(pictureBoxes.length, " placeholder PictureBoxes found: ", pictureBoxes);
	for (idx in pictureBoxes)
	{
		var pictureBox = pictureBoxes[idx];
		Editor.pictureBoxesLoaded[pictureBox.vbId] = 0;
		
	}
	
	// Get fonts for titles
	var allFonts = {};
	for (var idx in Editor.textsToResizeAfterFontLoaded)
	{
		var data = Editor.textsToResizeAfterFontLoaded[idx];
		var fontNames = data['font'];
		var fonts = fontNames.split(',');
		for (var i in fonts)
		{
			var font = $.trim(fonts[i]);
			allFonts[font] = 1;
		}
	}
	var fontFamilies = [];
	for (var fontName in allFonts)
	{
		fontFamilies.push(fontName);
	}		
	console.log("Waiting for fonts to load: ", fontFamilies);
	if (fontFamilies.length == 0)
	{
		// No fonts to load, continue immediately
		Editor.allFontsLoaded = true;
		Editor.PublishGeneratedWebsiteIfFinished();
		
	}
	else
	{
		// Font need to be loaded before continuing
		WebFont.load(
			{
		      custom: {
			    families: fontFamilies
			  },
			  active: function() {
				 console.log("Fonts Active"); 
				 Editor.OnAllFontsLoaded();
			  },
			  inactive: function() {
				 console.log("Font Inactive"); 
				 Editor.OnAllFontsLoaded();
			  }
			})
	}
}


Editor.OnAllFontsLoaded = function()
{
	if (Editor.allFontsLoaded) return;
	console.log("Texts to resize: ", Editor.textsToResizeAfterFontLoaded);
	for (var idx in Editor.textsToResizeAfterFontLoaded)
	{
		var data = Editor.textsToResizeAfterFontLoaded[idx];
		var richTextVb = data['vb'];
		Editor.ResizeRichText(richTextVb);
	}
	Editor.allFontsLoaded = true;
	Editor.PublishGeneratedWebsiteIfFinished();
}




Editor.OnPictureLoaded = function(pictureBox)
{
	if (!generateWebsite) return;
	if (Editor.allPicturesLoaded) return; // Don't call it twice, it will try to publish twice
	if (typeof(Editor.pictureBoxesLoaded[pictureBox.vbId]) == 'undefined') return; // Not a placeholder, skip
	
	Editor.pictureBoxesLoaded[pictureBox.vbId] = 1;
	var total = 0;
	var totalLoaded = 0;
	for (vbId in Editor.pictureBoxesLoaded)
	{
		var loaded = Editor.pictureBoxesLoaded[vbId];
		total++;
		if (loaded) totalLoaded++;
	}
	//console.log("PictureBox ", pictureBox.vbId, " loaded")
	console.log("Loaded ", totalLoaded, " out of ", total, " Placeholder PictureBoxes");
	//console.log(Editor.pictureBoxesLoaded);
	
	if (total == totalLoaded)
	{
		Editor.allPicturesLoaded = true;
		Editor.PublishGeneratedWebsiteIfFinished();
	}
}
	

//===================================== WEBSITE GENERATOR - PUBLISH ======================================//


Editor.PublishGeneratedWebsiteIfFinished = function()
{
	console.log("Call to publish website! Fonts loaded? ", Editor.allFontsLoaded, " / Pictures loaded? ", Editor.allPicturesLoaded);
	if (Editor.allFontsLoaded && Editor.allPicturesLoaded)
	{
		Editor.PublishGeneratedWebsite();
	}
}


Editor.PublishGeneratedWebsite = function()
{
	console.log("Fonts and Pictures fully loaded! Starting publish sequence for generated website");
	Editor.UpdateClones();


	CurrentWebsite().vbId = VbHelper.GenerateVbid();
	CurrentWebsite().vmName = 'website';
	CurrentWebsite().SaveToServerInternal(function(success)
	{
		if (!success)
		{
			alert('Cannot save to server. Sever returned: ' + success);
			return;
		}
		CurrentWebsite().PublishToServer(function(success)
		{
			if (!success)
			{
				alert('Cannot publish to server. Sever returned: ' + success);
				return;
			}
			else
			{
				$('.editor-loader').hide();

				Tracking.TrackEvent('im', 'fb_gen/website_generated');
				
				Generator.SendWallpost(function()
				{
					Tracking.TrackEvent('im', 'fb_gen/posted_to_wall');
					$.cookie('generated_'+CurrentWebsite().vbId, '1');
					// Redirect
					var websiteUrl = Configuration.GetTestDriveUrlForCurrentFile();
					if ((window.location.href.indexOf('localhost') != -1) || (window.location.href.indexOf('gotdns.com') != -1))
					{
						websiteUrl = '/view?vbid=' + CurrentWebsite().vbId;
					}
					
					//if (window.location.href.indexOf('fbgen') != -1)
					if (window.location.href.indexOf('fbgen') != -1)
					{
						//alert("FB GEN!");
						websiteUrl = '/view?vbid=' + CurrentWebsite().vbId;
					}
					console.log("Redirecting to: " + websiteUrl);			
					if (!generateWebsiteDebug)
						window.top.location.href = websiteUrl;
				
				});
			}
		});
	});

}





//===================================== WEBSITE GENERATOR - PLACEHOLDERS ======================================//


Editor.FillPlaceholders = function()
{
	// Find all placeholders
	var placeholders = Array();
	var clones = Array();
	Editor.GetPlaceholderVbs(CurrentWebsite(), placeholders, clones);
	console.log("Found placeholders: ", placeholders);
	// Fill the placeholders
	for (idx in placeholders)
	{
		var placeholder = placeholders[idx];
		Editor.ReplacePlaceholder(placeholder);
	}	
}



Editor.GetPlaceholderVbs = function(parent, list, clones)
{
	
	if (parent.vmPlaceholder != null && parent.vmPlaceholder != '')
	{
		var pushVb = true;
		if (parent.vmCloneId != null) // this is a clone
		{
			if (typeof(clones[parent.vmCloneId]) == 'undefined')
			{
				// This is the 1st clone (original). Modify it, we'll replicate it later using .updateClones()
				pushVb = true;
				Editor.pendingClones.push(parent);
			}
			else
			{
				// This is the 2nd, 3rd clones. Don't modify it. We'll override it later using .updateClones();
				pushVb = false;
			}
			clones[parent.vmCloneId] = 1;
		}
		if (pushVb)
		{
			list.push(parent);
		}
	}
	if (parent.vcChildren)
	{
		for (idx in parent.vcChildren)
		{
			var child = parent.vcChildren[idx];
			Editor.GetPlaceholderVbs(child, list, clones);
		}
	}
}



Editor.ReplacePlaceholder = function(vb)
{
	var key = vb.vmPlaceholder;
	var val = Generator.GetParam(key);
	if (val == null || (typeof(val)=='string' && $.trim(val) == ""))
	{
		console.warn("Cannot find value for placeholder: ", key);
		return; // Don't replace that placeholder
	}
	debug.log('Found placeholder "', key, '" on element "', vb.vbId, '". Let\'s fill it with: ', val);
	if (key == 'owner_name')
	{
		Editor.ReplaceRichText(vb, val);
	}
	else if (key == 'owner_headline')
	{
		Editor.ReplaceRichText(vb, val);
	}
	else if (key == 'owner_about')
	{
		Editor.ReplaceRichText(vb, val);
	}
	else if (key == 'owner_quote')
	{
		Editor.ReplaceRichText(vb, val);
	}
	else if (key == 'owner_picture_large')
	{
		Editor.ReplacePicture(vb, val);
	}
	else if (key == 'owner_tagged_pictures')
	{
		Editor.ReplacePictureSequence(vb, val);
	}
	else
	{
		debug.warn("Unhandles placeholder because type '"+content+"' is unrecognized:", vb);
	}
}


Editor.FindPlaceholderPictureBoxes = function(vb, list)
{
	var vbIsPlaceholder = (vb.vmPlaceholder != null) && (vb.vmPlaceholder != '');
	var parentIsPlaceholder = (vb.parent != null) && (vb.parent.vmPlaceholder != null) && (vb.parent.vmPlaceholder != '');
	if ((vbIsPlaceholder || parentIsPlaceholder) && vb.vmClass == 'PictureBox')
	{
		list.push(vb);
	}
	if (vb.vcChildren)
	{
		for (idx in vb.vcChildren)
		{
			var child = vb.vcChildren[idx];
			Editor.FindPlaceholderPictureBoxes(child, list);
		}
	}
}


Editor.textsToResizeAfterFontLoaded = new Array();

Editor.ReplaceRichText = function(richTextVb, newText)
{
	var children = richTextVb.contentElement.find('.textarea, .textarea *');
	
//	alert(richTextVb.contentElement.find('.textarea').html());
	var lastChild = null;
	var fontFamily = null;
	children.each(function()
	{
		var child = $(this);
		var nestedChildren = child.children("div,span,p").length;
		// If this element has no div/span/p's inside, and it's not empty, it's probably a text container
		var isTextContainer = nestedChildren == 0 && $.trim(child.text()) != "";
		if (isTextContainer)
		{
			child.html("");
			lastChild = child;
		}
		var thisFont = child.css('font-family');
		if (thisFont)
		{
			fontFamily = thisFont;
		}
	});
	if (lastChild)
	{
		lastChild.html(newText); 
	}
	else
	{
		console.log("NO SET");
	}
	//alert(richTextVb.contentElement.find('.textarea').html());
	
	richTextVb.SetText(richTextVb.contentElement.find('.textarea').html());
	richTextVb.InitContentBeforeShown();
	
	Editor.textsToResizeAfterFontLoaded.push({'vb': richTextVb, 'font': fontFamily});
}

Editor.ResizeRichText = function(richTextVb)
{
	// Show the page of the rich text, otherwise DownsizeText fails (return height=0)
	$('.creator .canvas .website > .child-container .page').hide();
	richTextVb.contentElement.parents('.page').show();
	// When replacing texts, we've changes the active page. Restore it to the first page
	$('.creator .canvas .website > .child-container .page:first').show();

	console.log("About to resize Rich Text: ", richTextVb);
	richTextVb.ResizeTo(richTextVb.vbWidth, richTextVb.vbHeight);
}


Editor.ReplacePicture = function(pictureBox, newPictureUrl)
{
	pictureBox.AddPicture(newPictureUrl, true);
}


Editor.ReplacePictureSequence = function(sequenceBox, pictureArray)
{
	sequenceBox.DeleteAllChildElements();
	for (var idx in pictureArray)
	{
		var picture = pictureArray[idx];
		var url = picture['url'];
		sequenceBox.AddPicture(url, true);
	}
	if (pictureArray.length > 0)
	{
		sequenceBox.SelectChildByIndex(0);
	}
}


//===================================== URL PARAMS AND SLUG ======================================//


Editor.GetVbidFromUrl = function()
{
	if (mode == 'edit' && !generateWebsite)
	{
		var slug = Editor.ParseUrlSlug();
		if (slug['vbid']) return slug['vbid'];
	}
		
	var param = jQuery.url.param("vbid");
	if (param) return param;
	
	return null;				
}

Editor.ParseUrlSlug = function()
{
	// Track URL hash slug change
	var slug = $.address.path();
	slug = slug.substring(1); // remove leading slash
	var parts = slug.split('/');
	var vbid = null;
	if (parts.length >= 1)
	{
		vbid = parts[0];
	}
	return {'vbid': vbid};
}




Editor.UpdateUrlSlug = function()
{
	// Don't put the same hash and param, only if they are different
	if (Editor.GetVbidFromUrl() != CurrentWebsite().vbId)
	{
		var slug = CurrentWebsite().vbId;
		$.address.value(slug);
	}
}


