/**
 * Unify core javascript engine
 *
 * @author Unify
 * @version v1.1
 */

/* Functions: Startup
----------------------------------------------- */
$(document).ready(function() {	
	initButtons();
	initMenus();	
	initHelpBoxes();
	initToolbox();
});


/* Global variables
----------------------------------------------- */
var RecaptchaOptions = {
   theme : "clean"
};
	

/* Functions: Getters
----------------------------------------------- */

/**
 * Capitalize the first letter of a string
 *
 * @param   string   string   String of which the first letter to be capitalized
 */
function ucFirst(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}



/**
 * Transcribe the AJAX feedback message to a readable and neat format
 *
 * @param   string   feedback   Feedback in delimiter (|) format
 */
function catchFeedback(feedback) {
	
	// Check if there is feedback
	if (feedback.length == 0) {
		return true;
	}
	
	// Split the feedback into an array
	feedbackArray = feedback.split('|');
	
	// Scroll to the top of the page
	$("html,body").animate({scrollTop: 0}, 300);
	
	// Is AJAX debugging on?
	if (logAjax == true) {
		addFeedback("ajax", "Ajax debug", feedback);
	}
	
	// Show feedback
	addFeedback(feedbackArray[0], feedbackArray[0], feedbackArray[1]);
	
	// Return
	if (feedbackArray[0] == "Success") {
		return true;
	} else {
		return false;
	}
}


/**
 * Show the feedback
 *
 * @param   string   type      Type of feedback message
 * @param   string   title     Title of the feedback message
 * @param   string   message   Feedback message
 */
function addFeedback(type, title, message) {
	
	// Translate title
	title = (lang[title.toLowerCase()] == undefined ? title : lang[title.toLowerCase()]);
	
	// Add feedback message
	$("div#feedback").append('<div class="feedbackContainer ' + type.toLowerCase() + '"><div class="flag"></div><div class="title">' + title + '</div><div class="text">' + message + '</div></div>');
	
	// Animation
	$("div#feedback div.feedbackContainer:last-child").show().delay(10000).animate({"margin-left" : "-" + $("div#feedback div.feedbackContainer:last-child").outerWidth(true) + "px"}, 800, function() { $(this).remove(); });		
}


/**
 * Token request
 */
function getToken() {
	
	// Get random number
	var randomizer = new Date().getTime();

	// Fetch the token
	var token = $.ajax({url: "core/handler.php?m=core&a=getToken&" + randomizer, async: false}).responseText;
	
	// Encode the token
	return(md5("#@!m/o&&i*jceA&EZohH;^{}" + token + "6)5ED4qsgq{6EZ&FZEtr=m&;&8(4zeNENzf864"));
}


/**
 * Fetch GET-string from url
 *
 * @param   boolean   returnString   Should a string or an array be returned?
 */
function fetchGetString(returnString) {

	var e,
	    d = function (s) { return decodeURIComponent(s.replace(/\+/g, " ")); },
	    q = window.location.search.substring(1),
	    r = /([^&=]+)=?([^&]*)/g;
	var toString = "";
	var toArray = {};

	while (e = r.exec(q)) {
		if (returnString == true) {
			toString += "&" + d(e[1]) + "=" + d(e[2]);
		} else {
			toArray[d(e[1])] = d(e[2]);
		}		
	}
	
	if (returnString == true) {
		return toString.substring(1, toString.length);
	} else {
		return toArray;
	}
}


/* Functions: Statics
----------------------------------------------- */

/**
 * Show or hide a form
 */
function showForm(id, show, loaderIcon) {
	
	$(id).fadeTo(0, 0);
	
	if (show == true) {
		$(id.replace("form", "div#loader")).remove();
		$(id).fadeTo(700, 1);
	} else {
		if (loaderIcon == true) {
			$(id).before('<div id="loader"></div>');
		}
	}
}

/**
 * About box
 */
function aboutBox() {

	// Build dialog box
	createDialog("aboutBox", 350, 500, getDialogButtons("aboutBox"));
}


/**
 * Get redirected to a certain page
 *
 * @param   string   url    The url to be directed to
 * @param   integer  time   Time in milliseconds
 */
function redirectTo(url, time) {
	setTimeout("window.location.href='"+ url +"'", time);
}


/**
 * Initialise menus (top right)
 */
function initMenus() {
	
	// Hide menus when left mouse button is clicked anywhere on the webpage
	$(document).bind('click', function(event){
		if($("div.menu").css("display") != "none"){
			event.stopPropagation();
		
			// Get menu Id
			var menuId = "div#" + $(event.target).parent().attr("menu");
			
			// Close menu
			if ((event.button == 0) && (!$(event.target).hasClass("menuButton") && !$(event.target).parent().hasClass("menu") && !$(event.target).parent().hasClass("menuContent") && !$(event.target).parent().hasClass("menuButton"))) {
				hideMenus();
			}
		}
		
		
	});
	
	// Change menu html
	$("div.menu").each(function(){
		
		// Get menu id
		var menuId = $(this).attr("id");
		
		// Add top and bottom divs
		$(this).prepend('<div class="imgStoreLayout menuTop"></div>').append('<div class="imgStoreLayout menuBottom"></div>');
	});
	
	// Make buttons clickable
	$("div.menuButton, div.menuButton div").live('click', function(event) {
		event.stopPropagation();
		
		if ($(event.currentTarget).attr("id").length == 0) {
			var currentId = $(event.currentTarget).parent().attr("id");
		} else{
			var currentId = $(event.currentTarget).attr("id");
		}
		
		var menuId = "div#" + $("div#" + currentId).attr("menu");
		
		if ($(menuId).css("display") == "block") {
			hideMenus();
		} else {
			showMenu(currentId);
		}	
		
	});
	
	// Logout (special case)
	$("a#logout").click(function(event) {
		
		// Stop link from working
		event.preventDefault();
		
		// Hide everything in Content DIV
		$("div#content").html('<div id="loader"></div><p>&nbsp;</p><p>&nbsp;</p>');
		
		// Log out (via ajax)
		var logout = $.ajax({url: "core/handler.php?m=users&a=logout&token=" + getToken(), async: false}).responseText;
		
		// Get feedback and redirect
		catchFeedback(logout);
		redirectTo("?", 1000);
	})
}

/**
 * Display a menu
 * 
 * @param   string   menuButtonId   Id the current menuButton
 */
function showMenu(menuButtonId) {
	
	// Change menu button id
	menuButtonId = "div#" + menuButtonId;
	
	// Get menu id
	var menuId = "div#" + $(menuButtonId).attr("menu");
		
	// Get menubutton coordinates
	var menuButtonLeft = $(menuButtonId).offset().left;
		
	// Get menu and menu button width
	var menuWidth = $(menuId).width();
	var menuButtonWidth = $(menuButtonId).width();
		
	// Highlight menu button
	$(menuButtonId).css({"background" : "url(./core/images/imgstore.background.png) 0px -78px repeat-x"});
	
	// Set coordinates and display menu
	$(menuId).css({"display" : "block", "top" : "37px", "left" : (menuButtonLeft-menuWidth+menuButtonWidth+10)+"px"});
}

/**
 * Hide all menus
 */
function hideMenus() {
	$("div.menu").css({"display" : "none"});
	$("div.menuButton").css({"background" : "none"});
}


/**
 * Initialise global form buttons
 */
function initButtons() {
	
	// Home icon redirects to CPanel
	$("div#navigationHome").click(function() {
		redirectTo("?", 0);
	});	
	
	// Redirect (non-dialog) cancel buttons to CPanel
	$("button.cancel").click(function() {
		redirectTo("?", 0);
	});
}


/**
 * Initialise help boxes
 */
function initHelpBoxes() {
	
	var fadeOut = 0.4
	
	// Fade help boxes (they don't have to stand out on the page)
	$("div.helpBox").fadeTo(0, fadeOut);
	
	// Set hover status
	$("div.helpBox").hover(
		function () {
			$("div.helpBox").fadeTo(400, 1);
		},
		function () {
			$("div.helpBox").fadeTo(400, fadeOut);
		}
	);
	
}


/**
 * Run a function, which name consists of a prefix (underscore) suffix (glued together)
 *
 * @param   string / array  name   string or array that contains the function name
 * @param   string   		glue   Glue to join the array
 */
function runFunction(name, glue) {
	// Check if name is array
	if(typeof(name) == "object"){
		glue = (glue == null) ? "": glue;
		// Create function name
		name = name.join(glue);
	}

	// Create javascript command
	if(checkFunction(name)){
		var functionName = name + "();";
		// The new function
		var fn = new Function(functionName);
		// Run the function
		fn();
		
		return true;
	}else{
		return false;
	}
}

/**
 * Run a function, which name consists of a prefix (underscore) suffix (glued together)
 *
 * @param   string  name   string or array that contains the function name
 */
function checkFunction(name){
	return typeof(window[name]) == "function";	
}

/**
 * Initialise the toolbox
 */
function initToolbox() {
	
	initToolboxRowButtons(0);
	
	// Initialise toolbox menubar
	$("div.toolbox.menubar button").each(function(index) {
		
		// Get the current class
		currentClass = $(this).attr("class");
		
		// Change into a jQuery button
		$(this).button({ icons: { primary: "ui-icon-" + currentClass } });
	});
	
	
	$("div.toolbox.row div, div.toolbox.menubar button").live('click', function(event) {
		// Fetch which dialog window should be opened
		var dialog = $(this).attr("dialog");
		
		// Get the type of dialog (add, edit, delete)
		var dialogType = $("div#" + dialog).attr("type");

		// Based on dialogType: perform action
		switch (dialogType) {
			case "add":
				createRow = $(event.target).closest('tr')[0];
				
				// Regular "add" button
				if ($(createRow).attr("id") == null) {
					crudAddRecord(dialog);
				
				// Add button which adds a new record on a certain place
				} else {
					crudAddRecordWithIdentifier(dialog, $(createRow).attr("id").substring(2));	
				}
				
				break;
			
			case "edit":
				editRow = $(event.target).closest('tr')[0];
				
				if($(this).attr("callback") == null){
					crudChangeRecord(dialog, $(editRow).attr("id").substring(2), $(editRow).attr("specialid"));
				}else{
					crudChangeRecord(dialog, $(editRow).attr("id").substring(2), $(editRow).attr("specialid"), $(this).attr("callback"));
				}
				break;
			
			case "delete":
				deleteRow = $(event.target).closest('tr')[0];
				if($(this).attr("callback") == null){
					crudChangeRecord(dialog, $(deleteRow).attr("id").substring(2), $(deleteRow).attr("specialid"));
				}else{
					crudChangeRecord(dialog, $(deleteRow).attr("id").substring(2), $(deleteRow).attr("specialid"), $(this).attr("callback"));
				}
				break;
		}
		
	});
	
	$("div.toolbox.regular div").live('click', function(event) {
		// Fetch which dialog window should be opened
		var dialog = $(this).attr("dialog");
		
		// Get the type of dialog (add, edit, delete)
		var dialogType = $("div#" + dialog).attr("type");
		
		// Based on dialogType: perform action
		switch (dialogType) {			
			case "edit":
				editMain = $(event.target).closest('div.main')[0];
				crudChangeRecord(dialog, $(editMain).attr("id").substring(2), $(editMain).attr("specialid"));
				break;
			
			case "delete":
				deleteMain = $(event.target).closest('div.main')[0];
				crudChangeRecord(dialog, $(deleteMain).attr("id").substring(2), $(deleteMain).attr("specialid"));
				break;
		}
	});
	
}


/**
 * Initialise the toolbox row buttons (optionally: only for a certain row)
 *
 * @param   string   rowId   Row id in which the toolbox buttons should be initialised
 */
function initToolboxRowButtons(rowId) {
	
	var container = "div.toolbox div";	
	
	// Only initialise a certain row	
	if (rowId > 0) {
		container = "tr#" + rowId + " " + container;
	}
	
	// Change div classes to jQuery UI classes
	$(container).each(function(index) {
		
		// Get the current class
		currentClass = $(this).attr("class");
		
		// Don't alter twice
		if ((currentClass != "ui-state-default ui-corner-all") && ($(this).children().size() == 0)) {
			$(this).attr("class", "ui-state-default ui-corner-all");
			$(this).html('<span class="ui-icon ui-icon-' + currentClass + '"></span>');
		}
	});
	
	// Hover states on toolbox icons
	$('div.toolbox div').live('mouseover mouseout', function(event) {
		if (event.type == 'mouseover') {
			$(this).addClass('ui-state-hover');
		} else {
			$(this).removeClass('ui-state-hover');		
		}
	});
	
}


/**
 * Prevent default form submission on key press enter
 *
 * @param   string   dialogId   Dialog id 
 */
function initPreventDefault(dialogId){
	$("div#" + dialogId).live("keypress", function(e){
		if (e.keyCode  == 13){
			e.preventDefault();
			var type = $(this).attr("type");
			var fn = dialogId + "_cb" + ucFirst(type);
			window[fn]();
		}
	});
}
