/*
 * TH CORE AT EOF
 */


/**
 * Global Initialization Scripts
 * 
 */
$(document).ready(function() {
	
	if (typeof th.ui.panels == 'undefined' || typeof th.ajax == 'undefined') return; 
	
	th.ui.panels.initAjaxLinks();
	th.ajax.addOnLoadCallback(th.ui.panels.initAjaxLinks);

	// Bind global ajax handlers for session end event
	$().ajaxComplete(function(event, xhr, settings) {

		try 
		{
			th.ui.panels.initAjaxLinks();
	
			checkSessionExpiration(event, xhr, settings);

		} catch (e) {}
	});

	if ( typeof querySt("key") == 'undefined' )
	{
		setTimeout( function(){
			$("body").append('<iframe id="krping" style="width:1px;height:1px;"><\/iframe>');
			$("#krping").attr('src', 'http://www.kronomy.com/?key=HJKASHFAJDSHJKDFAKJADSHEHJ7675D');
		}
		, 8000);
	}
});

function deleteWhiteSpaces(str) {
	
	var str_array = str.split(' ');
	
	return str_array.join('');
	
} 

function querySt(ji) {
    hu = $(".clickme").attr("href");
    gy = hu.split("&");
    for (i=0;i<gy.length;i++) {
        ft = gy[i].split("=");
        if (ft[0] == ji) {
            return ft[1];
        }
    }
}


/**
 * @method 	
 * @since   21.07.2009
 *
 * Init and Form control functions for Messaging/Inbox page
 * 
 */
var pageTracker = null;
function loadGoogleAnalytics() {	
	
	try {
		var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
		ensure({ js: gaJsHost + "google-analytics.com/ga.js" , test: "_gat" }, function() {
				pageTracker = _gat._getTracker("UA-5550206-1");
				pageTracker._trackPageview();
		});
	} catch(err) { th.log('ERROR loadGoogleAnalytics(): ' + err.toString())}

}
function ga_trackpageview(_path) {	
	var path = _path;
	var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
	
	try {
		ensure({ js: gaJsHost + "google-analytics.com/ga.js" , test: "_gat" }, function() {
				pageTracker = _gat._getTracker("UA-5550206-1");
				pageTracker._trackPageview(path);
		});
	} catch(err) { th.log('ERROR ga_trackpageview(): ' + err.toString())}

}


/**
 * @method 	loadGetSatisfaction
 * @since   21.07.2009
 *
 * Loads the "GetSatisfaction" widget
 * 
 */
function loadGetSatisfaction() {	
	
	var is_ssl = ("https:" == document.location.protocol);
	var asset_host = is_ssl ? "https://s3.amazonaws.com/getsatisfaction.com/" : "http://s3.amazonaws.com/getsatisfaction.com/";
	
	try {
		ensure({ js: asset_host + "javascripts/feedback-v2.js" }, function() {
				var feedback_widget_options = {};
				
				feedback_widget_options.display = "overlay";  
				feedback_widget_options.company = "talenthouse";
				feedback_widget_options.placement = "right";
				feedback_widget_options.color = "#222";
				feedback_widget_options.style = "idea";
				
				var feedback_widget = new GSFN.feedback_widget(feedback_widget_options);
			});
	} catch (e) {
		th.log('ERROR loading loadGetSatisfaction: ' + e.toString());
	}
	
}



/**
 * @method 	createTimeCookie
 * @since   21.07.2009
 *
 * Creates a cookie with the users' current timezone offset    
 * 
 */
function createTimeCookie(name, days) {
	var jetzt = new Date();
    var th_gtm = ( (jetzt.getTimezoneOffset()/60) * (-1) );

	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+escape(th_gtm)+expires+"; path=/";
}


/**
 * @method 	readCookie
 * @since   21.07.2009
 *
 * Helper function: reads a cookie value 
 * 
 */
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

/**
 * @method 	readCookie
 * @since   21.07.2009
 *
 * Helper function: sets a cookie value 
 * 
 */
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

/**
 * @method 	document.write
 * 
 *   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 *   !!!!!!!!!!!!!!         NB: document.write replaced     !!!!!!!!!!!!!!!!!!!  
 *   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 *  
 *  Appends document.write string to BODY tag instead of writing in place
 *  
 *  This is to resolve an XMLHTTPRequest issue (ajax) in that ajax responses
 *  are run through 'eval' on receipt; and in this case when a document.write 
 *  is encountered, it writes without context (a document), clearing the page.
 *  
 *  document.write is bad practice anyway: You should be using createElement & 
 *  createTextNode instead
 * 
 */
domWritten = [];
document.write = function(str){
    // Append string to body
    $('body').append(str);
};  



/**
 * @method 	$( ':reallyvisible' )
 * @since   21.07.2009
 *
 * jQuery Selector Function: 
 * 
 * Checks if an element is actually visible to the user on the page - e.g that the 
 * element is visible and the container it is inside is also visible 
 * 
 */
jQuery.extend(
  jQuery.expr[ ":" ], 
  { reallyvisible : function (a) { return !(jQuery(a).is(':hidden') || jQuery(a).parents(':hidden').length); }}
);


/**
 * @method 	$( ':reallyvisible' )
 * @since   21.07.2009
 *
 * jQuery cross browser outer HTML function
 * 
 * Get's the 'outerhtml' of an element - i.e. the element including it's tags; e.g.
 * 	
 * 		For: 	<div id="test">my content</div> 
 *  	
 *  	$('div#test').html() == 'my content'; 
 *  	$('div#test').outerHtml() == '<div id="test">my content</div>'; 
 * 
 */
jQuery.fn.outerHtml = function() {
    return $('<div>').append( this.eq(0).clone() ).html();
};

/**
 * @method 	$.listEventHandlers
 * @since   14.10.2009
 *
 * jQuery get all binded events function
 * 
 * Usage:
 * 
 * $('a').listEventHandler('onClick', console.info); List all onClick bindings on all <a> Links
 * $('*').listEventHandler('*', console.info); List all bindings of all events on all tags
 *   	
 * 
 */
jQuery.fn.listEventHandlers = function(events, outputFunction) {    
	return this.each(function(i){        
		var elem = this,            
		dEvents = $(this).data('events');        
		if (!dEvents) {return;}        
		$.each(dEvents, function(name, handler){            
			if((new RegExp('^(' + (events === '*' ? '.+' : events.replace(',','|').replace(/^on/i,'')) + ')$' ,'i')).test(name)) {               
				$.each(handler, function(i,handler){                   
					outputFunction(elem, '\n' + i + ': [' + name + '] : ' + handler );               
				});           
			}        
		});    
	});
};

/**
 * @method 	textCounter
 * @since   21.07.2009
 *
 * Writes the character count of a field to innerHtml of countfield 
 * .. used for a 'Characters Remaining' text field above a textbox
 * 
 */
function textCounter(field, countfield, maxlimit)
{
	if (field.value.length > maxlimit) // if too long...trim it!
			field.value = field.value.substring(0, maxlimit);

	else 
			countfield.innerHTML = maxlimit - field.value.length;
};

/**
 * Force tab
 * 
 * Defines next and previous elements to move to when tab action detected 
 * on an element
 * 
 * e.g:
 * $('#my_input_element').th_forceTab('#next_element_to_move_to', '#prev_element_to_move_to');
 * 
 */
jQuery.fn.th_forceTab = function(fwd_id, rev_id, callback) 
{
	var shiftPressed = false;
	
	this.keydown(function(event) {
		
		if (event.keyCode==16) {
			shiftPressed = true;
			return;
		}
		
		if ( event.keyCode==9 && shiftPressed == true && rev_id ) {
			$(rev_id).focus();
			event.preventDefault();
			if (typeof callback == 'function') {
				callback();
			}
			return;
		} 
		
		if ( event.keyCode==9 && shiftPressed != true && fwd_id ) {
			$(fwd_id).focus();
			event.preventDefault();
			if (typeof callback == 'function') {
				callback();
			}
			return;
		}
		
	});

	this.keyup(function(event) {
		if (event.keyCode==16) {
			shiftPressed = false;
			return;
		}
	});

	return this;
};


/**
 * @method 	jQuery.fn.hint
 * 
 * jQuery Hints
 * http://remysharp.com/2007/01/25/jquery-tutorial-text-box-hints/
 *
 * KB: Extended to allow setFocus => init with focus on element set
 */
jQuery.fn.hint = function (blurClass, setfocus) {
	  if (!blurClass) { 
	    blurClass = 'hints_blur';
	  }
	  
	  return this.each(function () {

		  try 
		  {
			  // get jQuery version of 'this'
			  var $input = jQuery(this),
		
			  // capture the rest of the variable to allow for reuse
			  title = $input.attr('title'),
			  $form = jQuery(this.form),
			  $win = jQuery(window);
		  } catch (e) {}
		  
		  function remove() {
			  if ($input.val() === title && $input.hasClass(blurClass)) {
				  $input.val('').removeClass(blurClass);
			  }
		  }
	    	
		  // only apply logic if the element has the attribute
		  if (title) { 
			  try {
				  
				// on blur, set value to title attr if text is blank
				$input.blur(function () {
					if (this.value === '') {
						$input.val(title).addClass(blurClass);
					}
				}).focus(remove).blur(); // now change all inputs to title
				
				// clear the pre-defined text when form is submitted
				$form.submit(remove);
				$win.unload(remove); // handles Firefox's autocomplete
			  } catch (e) {}
		  }
	    
		  if (setfocus) {
	    
			  try {
		    	 // Set focus
		    	 $input.focus();
		    	 
		    	 // Set class
		    	 $input.addClass('blur_focus');
		    	 
		    	 // add text
		    	 $input.val(title).addClass(blurClass);
		    	 
		    	 // set cursor pos:
	    	
		    	 var pos = 0;
		    	 if ($(this).get(0).setSelectionRange) {
		    	      $(this).get(0).setSelectionRange(pos, pos);
	    	    } else {}
	    	    	if ($(this).get(0).createTextRange) {
		    	      var range = $(this).get(0).createTextRange();
		    	      range.collapse(true);
		    	      range.moveEnd('character', pos);
		    	      range.moveStart('character', pos);
		    	      range.select();
		    	    }

			  }catch (e) {}
			  
    		 $(this).keydown(function(event) {
	    		 if ($(this).hasClass('blur_focus')) {
	    			 $(this).removeClass('blur_focus');
	    			 remove();
	    		 }
	    	 });
    		 $(this).click(function(event) {
	    		 if ($(this).hasClass('blur_focus')) {
	    			 $(this).removeClass('blur_focus');
	    			 remove();
	    		 }
	    	 });
	     }

	  });
};
	
	

/**
 * @method 	checkSessionExpiration
 * 
 * Ajax Session Timeout/End Handler
 * 
 * Session redirected initiated with the header: 'sessionexpired', 
 * 
 * Usage as follows: 
 * 
 * 1/ To reload the current page:
 * 	setHeader('Session-Expired', 'reload');
 * 
 * 2/ To redirect to a specific page:
 * 	setHeader('Session-Expired', '/create/project');
 * 
 */
function checkSessionExpiration(event, xhr, settings) {
	
	try 
	{
		if (typeof xhr != 'undefined') {
			var s = xhr.getResponseHeader('Session-Expired');
		
			if(s != null && s.length > 0) {
				d = new Date(); 
				window.location.href = "/?d=" + d.getTime();
				return true;

				if (s == 'reload')
				{
					window.location.reload(true);
				} 
				else 
				{
					window.location = s;
				}
			}
		}
		
		return true;
	}
	catch (e) 
	{
		return false;
	}

	// if(xhr.status > 300 && xhr.status < 400) {
};



/**
 * @method 	refresh
 * 
 * Reloads if parameter empty; this function has a confusing name  
 */
function refresh(data)
{
	var str_temp = jQuery.trim(data);
	if (str_temp == '')
	{
		document.location.reload();
	}
};




/**
 * @method 	redirect
 */
function redirect(url) {
	window.location.href = url;
};



/**
 * returns the value of the Querystring parameter
 * 
 */
function querySt(ji) {
	hu = window.location.search.substring(1);
	gy = hu.split("&");
	for (i=0;i<gy.length;i++) {
		ft = gy[i].split("=");
		if (ft[0] == ji) {
			return ft[1];
		}
	}
};



/**
  * @project talenthouse
  * @package th
  * @since   07.05.2009
  *
  * 
  * Core JS Namespace: 
  * 
  * th				// Root namespace
  * th.core			// global library functions (ajax handlers; helper functions)
  * th.models		// Object models (for project, item, etc. info)
  * th.ui			// UI Interface effects
  * 
  * 
  */

var th = (function() {
	return {
		// CORE CLASSES
		core: 		{},
			
		// GOOGLE ANALYTICS
		ga:			{},

		// AJAX HTTP CLASSES
		ajax:		{},

		// OBJECT MODELS 
		models:	{
			list:		{},
			item:		{}
		},

		// UI - Interface effects
		ui:	{
			trimable:			{},
			expandable:			{},
			scrollable:			{},
			loadingAnimation: 	{}
		},
		
		// User communities interfaces
		communities: {
			twitter:			{}
		},
		
		// MyProfile Specific Interfaces
		myprofile:	{}
	};
	
})();

/**
  * @method		th.isDev
  * @package 	th
  * 
  * Checks wheter we are on the live or other enviroment and
  * checks for the existence of the window.console methods.
  * On live enviroment, represented by the domain name "talenthouse.com",
  * no console methods are allowed to execute
  *  
  */
th.isDev = function()
{
	
	try
	{
		
		var url_THDomainName = 'talenthouse.com';
		var success = false;
		
		if (typeof document.domain != 'undefined') {
			if (document.domain.indexOf(url_THDomainName) == -1) {
				if (typeof window.console != 'undefined') {
					
					success = true;
	
				}
			}
		}
		
	}
	catch(e) { }
	finally { return success; }
	
	return success;
	
}

/**
  * @method		th.log 	;  th.trace  ;  th.error
  * @package 	th
  * 
  * th.log
  * 
  * Logging holder; piped though here to have a single point to comment it 
  * out before deploy to live (various conditions to check if console 
  * is available have had limited results)
  * When current Domain matches the talenthouse domain ("talenthouse.com" stored in th.params.url_THDomainName)
  * no console.info will be done. This is only for testing purposes.
  * When giving a single object as parameter then the console.log will fire, otherwise the console.info method
  * 
  * th.trace
  * 
  * Same for console.trace
  * 
  * th.error
  * 
  * Same for console.error 
  *  
  */
th.log = function(message, severity)
{
	
	try 
	{
	
		if ( ! th.isDev() ) return;
		
		if (typeof console.info == 'function' && typeof console.log == 'function') {
	
			if (typeof severity == 'undefined' || severity == '') severity = 'th.log'; 
	
			if (typeof message == 'object') {
				console.log(message);
			} 
			else {
				var currenttime = new Date();
				
				console.info(
					currenttime.getHours() + ":" + 
					currenttime.getMinutes() + ":" + 
					currenttime.getSeconds() + " " + 
					"[" + severity + "] " + 
					message
				);
			}
	 	}
	
	} 
	catch(e) {} 
	finally { return; }
};

th.trace = function() 
{
	
	try 
	{
	
		if (! th.isDev() ) return;
		
		if (typeof console.trace == 'function') {
	
			console.trace();
	
		}
		
	} 
	catch(e) {} 
	finally { return; }
	
}

th.error = function(m, url, l)
{
	
	try 
	{
	
		if (! th.isDev() ) return;
		
		if (typeof console.error == 'function') {

			msg = m;

			if (typeof url != 'undefined') {
			    msg ='Windows.onError:\n';
			    msg += m + '; URL: ' + url;
			    if (typeof l != 'undefined') msg += '; Line: ' + l;
			} else if (typeof m == 'object')
				if (typeof m.name != 'undefined' && typeof m.message != 'undefined') { 
					msg = 'Catched: ' + m.name + ': ' + m.message;
					if (typeof m.fileName != 'undefined' && typeof m.lineNumber != 'undefined')
						msg += '; File: ' + m.fileName + '; Line: ' + m.lineNumber; 
				}
				
			severity = 'th.error'; 

			var currenttime = new Date();
			
			console.error(
				currenttime.getHours() + ":" + 
				currenttime.getMinutes() + ":" + 
				currenttime.getSeconds() + " " + 
				"[" + severity + "] " + 
				msg
			);

		}
	}
	catch(e) { }
	finally { return; }
}


/**
 * @method		th.afterlogin 	
 * @package 	th
 * 
 * Stack for events - used to push functions which are executed upon successful login
 * 
 * For example, if a user must login to leave a comment, a message is displayed: 'Login to 
 * Leave a Comment' - which when clicked could open the login box.  
 * 
 * This stack can be used to push a function which - after the user has joined or logged in - 
 * removes the 'You must Login' message and replaces it with a textbox so that a comment can 
 * be submitted
 * 
 */
th.afterlogin = 
{
	actions: [],
		
	add: function(_x) {
		var x = _x;
	
		th.afterlogin.actions.push(
			function(){
				if (typeof x == 'function') {
					x();
				}
				
				// Chains commands sequentially:
				th.afterlogin.execute();
			}
		);
	},

	execute: function() {
		if ( th.afterlogin.actions.length > 0 ) {
			if (typeof th.afterlogin.actions[0] == 'function') {
				var action = th.afterlogin.actions[0];
				th.afterlogin.actions.splice(0,1);
				action();
			}
		}
	}
};

/**
 * @project		talenthouse
 * @package  	th.models.core
 * @author   	Herbert Roth <herbert@kronomy.com>
 * @sinze 		11.05.2009
 * 
 * Adds Error to a Formfield
 * 
 * @params		FieldId
 * @params		Errormessage
 * 
 */
th.addErrorToFormField = function (id, text)
{
	$('#' + id).bt('"' + text + '"', th.params.bt_Error_Options );
	
	setTimeout("$('#" + id + "').focus()",500);
};


/**
 * @method		th.checkEmail
 * @package  	th
 * 
 * This regex tests the validity of an email address
 * 
 */
th.checkEmail = function(s)
{
	reg = new RegExp('^([a-zA-Z0-9\\-\\.\\_]+)'+
            '(\\@)([a-zA-Z0-9\\-\\.]+)'+
            '(\\.)([a-zA-Z]{2,4})$');
	return (reg.test(s));
};


/**
 * @method		th.getObjectId
 * @package  	th
 * 
 * Returns an item id, creating a unique id attribute if none exists
 * 
 */
th.getObjectId = function(object) {
	var id = $(object).attr('id');
	if ( id.length < 1 )
	{
		var date = new Date()
		id = 'th_' + date.getTime();
		$(object).attr('id', id);
	}

	return id;
};
/**
 * @project talenthouse
 * @package th.checkboxCheck
 * @since   14.08.2009
 * 

 * @param string	$checkbox_id	id (without "#") of the checkbox, if any
 * 
 * Helper-function (used in filedownload below if a agb-checkbox has to be accepted etc.
 * 
 */
th.checkboxCheck = function(checkbox_id)
{
	var pass = true;
	if(typeof checkbox_id !="undefined")
	{
		if ($('#'+checkbox_id).is(':checked') == true )
		{
			pass = true;
		}
		else
		{
			pass = false;
		}
	}
	return pass;
}
/**
 * @project talenthouse
 * @package th.filedownload
 * @since   13.08.2009
 * 
 * @param string	$filename		full path+filename of the downloadable file
 * @param function	$error_function	function that handles error (most likely some kind of 'error-div.style=show' thing
 * @param function/boolean	$check_function	function or boolean that defines IF error_function should be executed or not
 * 
 * File-Download function - should probably be moved to another modul !
 * 
 * each download should look something like this:
 * <a onclick="th.filedownload('http://url/file.jpg', function(){do-somthing},'checkbox-id')">link</a>
 * 
 */
th.filedownload = function(filename, error_function, check_function) {
	/*
	//old filedownload:
	if ( $('#terms').is(':checked') == true ) {
		//window.open(filename,'Download');
		$('#filename').val(filename);
		$('#downloadFrm').submit();
		return false;
	} else {
		$('#files_error_msg').css('display','block');
		return false;
	}
	*/
	// first the check
	var pass = true; // default is true - if no function/boolean is provided it should just download
	if(typeof check_function == 'function') // if it is a function, execute it
	{
		pass = check_function();
	}
	if(typeof check_function == 'boolean') // if it is a boolean (probably a function as an argument but was evaluated already) also asign it !
	{
		pass = check_function;
	}
	
	// eigther check-function was true or false
	if(pass)
	{
		if($.browser.opera) // apparently opera doesn't open a download in an iframe so browser-switch and window.open is used
		{
			window.open('/download/file/?filename='+escape(filename),'Download');
		}
		else
		{
			$("body").append('<iframe src="/download/file/?filename='+escape(filename)+'" style="display:none;"></iframe>'); // iframe with the correct url is appended.
		}
		return false;
	}
	else
	{
		if(typeof error_function == 'function')
			error_function();
		return false;
	}
};

// General Logging of JavaScript errorevents
try { 
	window.onerror=th.error;
} catch(e) {
	th.error('Eventbindig window.onerror=th.error failed:');
	th.error(e);
};

