
var TV = {}; // global namespace

// A utility function used to reset a form to somewhat basic values.
$.fn.reset = function() {
  return this.each(function() {
    var type = this.type, tag = this.tagName.toLowerCase();
    
    if (tag == 'form') return $(':input',this).reset();
      
    if (type == 'text' || type == 'password' || tag == 'textarea')
    {
      this.value = '';
    }
    else if (type == 'checkbox')
    {
      if(this.checked) this.click();
    }
    else if (tag == 'select')
    {
      // TODO: Make sure this fires any change handlers. If not, change this to fire handlers.
      this.selectedIndex = 0;
    }
    else if (type == 'radio')
    {
      // TODO: Figure out how to select the first radio in a group.
    }
  });
}

// A utility function that creates a fairly random password suggestion.
$.fn.suggestPassword = function (length, special) {
  var iteration = 0;
  var password = "";
  var randomNumber;
  if(special == undefined){
      var special = false;
  }
  while(iteration < length){
      randomNumber = (Math.floor((Math.random() * 100)) % 94) + 33;
      if(!special){
          if ((randomNumber >=33) && (randomNumber <=47)) { continue; }
          if ((randomNumber >=58) && (randomNumber <=64)) { continue; }
          if ((randomNumber >=91) && (randomNumber <=96)) { continue; }
          if ((randomNumber >=123) && (randomNumber <=126)) { continue; }
      }
      iteration++;
      password += String.fromCharCode(randomNumber);
  }
  return password;
}

// This function centers an element vertically and horizontally in code.
$.fn.center = function( p ) {
  var base = ( document.documentElement ? document.documentElement : document.body );
  var windowWidth = base.clientWidth;
  var windowHeight = base.clientHeight;
  var popupHeight = $( this ).height();
  var popupWidth = $( this ).width();
 
  $( this ).css({  
    "position": "absolute",  
    "top": ( p && p.top ? p.top : (windowHeight/2) - (popupHeight/2) + $(window).scrollTop()  + 'px' ),  
    "left": ( p && p.left ? p.left : (windowWidth/2) - (popupWidth/2) + 'px' )  
  });  
}

// This function submits a form via an Ajax call (jQuery).
$.fn.do_ajax = function( params ) {
  return this.each(function() {
    try {
      var type = this.type, tag = this.tagName.toLowerCase();
      
      if ( 'form' === tag ) // this function is meant to operate on <FORMS>
      {
        var method = this.method.toLowerCase();
        var url = this.action;
        
        params['method'] = method;
        params['url'] = action;
        
        if ( 'get' === method )
        {
          call_ajax( params );
        }
        else if ( 'post' === method )
        {
          call_ajax( params );
        }
        else {}
      } // not a form, so we do nothing...
    } catch (e) { /* TODO: When implemented, call octane.log(...) here. */ }
  });
}

// This function creates a dialog with the context element as the content of the dialog.
$.fn.dialog = function( params ) {
    
}

function roundify( sel, radius )
{
	if ( $.browser.msie )
  {
    DD_roundies.addRule( sel, radius );
  }
}

function call_ajax( params ) 
{
  var method = ( params && params.method ? params.method : 'post' );
  var frm;
  
  if ( method === 'post' )
  {
    frm = $( params.form );
  }
  else
  {
	  $.get( params.url, function( data ) {
  		var obj = new Function( "return " + data )();

  		if (obj.status > 0)
  		{
  			params.success_callback( obj );
  		}
  		else
  		{
  		  if ( params.failure_callback )
  		  {
  		    params.failure_callback( obj );
        }
        else
        {
  			 doAlert(obj.message);
        }
  		}
	  });
	  
	  return false;
  }
  
  if ( params && (( params.before_callback && params.before_callback( frm ) ) || !params.before_callback) )
  {
  	  if ( params.redirect_url ) 
  	  {
  	  	frm.append('<input name="redirect" type="hidden" value="' + params.redirect_url + '" />');
  	  }

	  $.post( params.url, frm.serializeArray(), function( data ) {
  		var obj = new Function( "return " + data )();
  		
  		if (obj.status > 0)
  		{
  			params.success_callback( obj );
  		}
  		else
  		{
  		  if ( params.failure_callback )
  		  {
  		    params.failure_callback( obj );
        }
        else
        {
  			 doAlert(obj.message);
        }
  		}
	  });
  }
  return false;
}


function get_element(s_id)
{
	return (document.all ? document.all[s_id] : (document.getElementById ? document.getElementById(s_id) : null));
}

function show_hide_categories(num)
{
	if (num == 1) {
		$("#more_categories_link").css( 'display', 'none' );
		$("#more_categories_list").css( 'display', '' );
	}
	else {
		$("#more_categories_list").css( 'display', 'none' );
		$("#more_categories_link").css( 'display', '' );
	}
}


function show_hide_leftside(num)
{
	if (num == 1) {
		get_element("lsidebar").style.display = 'none';
		get_element("refine_your_search_space").style.display = 'none';
		get_element("refine_your_search").style.display = '';
		var center_side = get_element("center_side");
    center_side.style.width = (parseInt(center_side.style.width) + 150) + 'px';
	}
	else {
		get_element("refine_your_search").style.display = 'none';
		get_element("refine_your_search_space").style.display = '';
		get_element("lsidebar").style.display = '';
		var center_side = get_element("center_side");
    center_side.style.width = (parseInt(center_side.style.width) - 150) + 'px';
	}
}

function hide_recent_job_searches()
{
	get_element("recent_job_searches_filter_record").style.display = 'none';
	get_element("recent_job_searches_filter_title").style.display = 'none';
}

function toggleRefineBy(img_elem,tr_elem)
{
	tr_disp = get_element(tr_elem).style.display;
	if (tr_disp == 'none') {
		get_element(tr_elem).style.display = '';
		get_element(img_elem).src = '/frontend/images/arrow_bottom.gif';
	}
	else {
		get_element(tr_elem).style.display = 'none';
		get_element(img_elem).src = '/frontend/images/arrow_right.gif';
	}
}

/*Delete stored in cookie "Recent Job Searches"*/
function delSearchCookie()
{
	var a = new Array();
	var c = new Date();
	var a = window.document.cookie.split(';');
	var	p = -1;
	
	//c.setYear(c.getYear() - 10);
	
	for (var i=0; i<a.length; i++)
	{
		p = a[i].indexOf("RecentJobSearchesTitle[");
		
		if (p >= 0) {
		  window.document.cookie = a[i] + ";expires=" + c.toGMTString() + ";path=/";
			continue;
		}
		
		p = a[i].indexOf("RecentJobSearchesLink[");
		
		if (p >= 0) {
			window.document.cookie = a[i] + ";expires=" + c.toGMTString() + ";path=/";
		}
	}
}

var caution = false;
function setCookie(name, value, expires, path, domain, secure)
{
	var curCookie = name + "=" + escape(value) +
			((expires) ? "; expires=" + expires.toGMTString() : "") +
			((path) ? "; path=" + path : "") +
			((domain) ? "; domain=" + domain : "") +
			((secure) ? "; secure" : "")
	if (!caution || (name + "=" + escape(value)).length <= 4000) document.cookie = curCookie
	else 
	if (confirm("Cookie length more then 4KB! Saved as many as possible.")) document.cookie = curCookie
}

// this fixes an issue with the old method, ambiguous values 
// with this test document.cookie.indexOf( name + "=" );
function getCookie(check_name) {
	// first we'll split this cookie up into name/value pairs
	// note: document.cookie only returns name=value, not the other components
	var a_all_cookies = document.cookie.split( ';' );
	var a_temp_cookie = '';
	var cookie_name = '';
	var cookie_value = '';
	var b_cookie_found = false; // set boolean t/f default f
	
	for (i=0; i<a_all_cookies.length; i++)
	{
		// now we'll split apart each name=value pair
		a_temp_cookie = a_all_cookies[i].split('=');
		// and trim left/right whitespace while we're at it
		cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
		// if the extracted name matches passed check_name
		if (cookie_name == check_name)
		{
			b_cookie_found = true;
			// we need to handle case where cookie has no value but exists (no = sign, that is):
			if (a_temp_cookie.length > 1)
			{
				cookie_value = unescape(a_temp_cookie[1].replace(/^\s+|\s+$/g, ''));
			}
			// note that in cases where cookie is initialized but no value, null is returned
			return cookie_value;
			break;
		}
		a_temp_cookie = null;
		cookie_name = '';
	}
	if (!b_cookie_found)
	{
		return null;
	}
}

function deleteCookie(name, path, domain)
{
	if (getCookie(name)) {
		document.cookie = name + "=" +
		((path) ? ";path=" + path : "") +
		((domain) ? ";domain=" + domain : "" ) +
		";expires=Thu, 01-Jan-1970 00:00:01 GMT";
	}
}

/*Save job to cookie (My Jobs)*/
function saveJobToCookie(jobkey)
{
	var exdate = new Date();
	exdate.setDate(exdate.getDate()+30*12);
	setCookie("MyJobs_save[" + jobkey + "]", "1", exdate, "/");
	alert_job_saved();
}

function hide_and_show_elements(elem1_id,elem2_id)
{
	get_element(elem1_id).style.display = 'none';
	get_element(elem2_id).style.display = '';
}

function hide_element(elem_id)
{
	$('#' + elem_id).css( 'display', 'none' );
}

function show_element(elem_id)
{
	$('#' + elem_id).css( 'display', '' );
}

/*Delete all jobs from cookie (My Jobs)*/
function deleteAllJobsFromCookie()
{
	var a = new Array();
	var c = new Date();
	var a = window.document.cookie.split(';');
	var	p = -1;
	for (var i=0; i<a.length; i++)
	{
		p = a[i].indexOf("MyJobs_save[");
		if (p >= 0) {
			var b = a[i].split('=');
			var cookie_name = b[0].replace(/^\s+|\s+$/g, '');
			deleteCookie(cookie_name, "/");
		}
	}
}

function clearValidation()
{
	$('#regform label .message').remove();
	$('#regform label.invalid').removeClass( 'invalid' );
}

function doAlert(msg)
{
	$('#msg_alert').text( msg ).show();
	setTimeout(hideAlert, 3000);
}

function hideAlert()
{
	$('#msg_alert').text('').hide();
}

function login_apply( event )
{
	call_ajax({
			'url' : '/login/',
			'method' : 'post',
			'form' : $( '#loginform' ),
			'success_callback' : function( result ){ 
				close_dialog();
				update_links( result );
				$('.regform_box').addClass('thanks');
				$('.regform_box').html('<h3 class="thanks">Thank you for applying!</h3>');
				window.open( event.data );
			 },
			'before_callback' : before_login
		});
	return false;
}

function validate( form )
{
  return true;
}

function doRequestPassword( value, event ) 
{ 
	call_ajax({
		'url' : '/requestpass/',
		'method' : 'post',
		'form' : $( value ),
		'success_callback' : function( result ){
		  	doAlert( result.message );
		  	close_dialog();
		  }
	});
	
	event.preventDefault();
	
	return false;
}

function check_all(event)
{
	$('td.checkcell input[type="checkbox"]').attr('checked', ( $('th.checkcell input:checked').length > 0 ));
}

function delete_jobalerts(event)
{
	$.post('/jobalert/delete/', $(this.form).serializeArray(), function(data){
		var obj = eval('(' + data + ')');
		
		if ( obj.status > 0 )
		{
  		for ( var i = 0; i < obj.ids.length; i++ )
  		{
  			$( 'input[value="' + obj.ids[i] + '"]' ).parents('tr').remove();
  		}
    }
		
		doAlert( obj.message );
	});
	return false;
}

function showRequestPassword(e)
{
	var frm = $('#formcontainer');
	var r = $('#passform');
	
	frm.animate({ 
		width: r.width() + 200,
		left: frm.offset().left - r.width()/3
	}, 400, 'swing');
  
	frm.removeClass( 'login' );
	frm.addClass( 'pass' );
  
	// it seems the DD_roundies library doesn't roundify the element if it is hidden...
	//roundify( '#formcontainer .button', '10px' );
  
	$('.dialog-title').text(r.attr('title'));
	
	return false;
}

function showMessage( msg )
{
  var frag = document.createDocumentFragment();
  var box = $(document.createElement('div'));
  box.html('<p>' + msg + '</p>');
  
  box.addClass( 'infobar' );
  //box.addClass( 'show' );

  $( '#mylinks' ).after( box );
  
  box.slideDown( 'slow' );
  
  setTimeout(function(){ $('.infobar').slideUp( 'fast' ) }, 3000);
}

function resetLogin(event)
{
	var frm = $( '#formcontainer' );
	
	// reset all of the styles we use to resize the dialog for the password form...
	frm.css( 'position', '' );
	frm.css( 'top', '' );
	frm.css( 'left', '' );
	frm.css( 'width', '' );
	frm.css( 'height', '' );
	frm.css( 'opacity', '' );
	frm.css( 'display', 'none' );
	
	frm.removeClass( 'dialog' );
	frm.removeClass( 'pass' );
	frm.removeClass( 'login' );
	
	return true;
}

function show_login( action, event, after_url )
{
	var frm = $( '#formcontainer' );
	var r = frm.find( '#loginform' );
	
	frm.find( '.dialog-titlebar-close' ).bind( 'click', function(){ close_dialog();return false; } );
	frm.css( 'display', '' );
	frm.addClass( 'dialog' );
	frm.removeClass( 'pass' );
	frm.addClass( 'login' );
	
	frm.center();
	
	// it seems the DD_roundies library doesn't roundify the element if it is hidden...
	roundify( '#formcontainer .button', '10px' );
  
	$( '.dialog-title' ).text( r.attr( 'title' ) );
	if ( action ) r.find( 'button' ).unbind().bind( 'click', after_url, action );
	r.find( '#username' ).focus();
}

function login_success( result )
{
	if ( result.redirect ) 
	{
		window.location.href = result.redirect;
		return;
	}
	
	if (result.message) 
	{
		doAlert(result.message);
		return;
	}
	
	close_dialog();
	update_links( result );
}

function close_dialog()
{
  resetLogin();
  //Dialog.close();
}

function update_links( result )
{
	if ( $( '#welcome_message_name' ).length > 0 ) return;
	
  	$( '#mylinks' ).append( '<li id="welcome_message_name">Welcome ' + result.user_name + '</li>' );
  	$( '#mylinks .loginlink' ).attr( 'href', '/logout/' ).removeClass( 'logoutlink' ).addClass( 'loginlink' ).text( 'Log Out' );	
  	//$( '#mylinks .employerlink' ).after( '<li><a class="logoutlink" href="/logout/">Log Out</a></li>' );	
  	$( '.requireslogin' ).unbind();
}

function before_login( form )
{
	var email = $(form).find('input[name="username"]').val();
	var pass = $(form).find('input[name="userpass"]').val();
	
	return (email && email != '' && pass && pass != '');
}

function setup_mylinks()
{
	if ( !is_loggedin() )
	{ 
		$('.requireslogin').unbind().bind( 'click', function( event ){
			show_login( login_action, event, this.href ); 
			return false;
		});
		
		$('.requireslogin.loginlink').unbind().bind( 'click', function( event ){
			show_login( login_action, event, window.location.href ); 
			return false;
		});
		
		setup_tooltip( $( '#mylinks .requireslogin' ), 'Click to Log In.');
	}
	
	setup_tooltip( $( 'li.myalertslink' ), 'Added Job Alert!', {'trigger':'none'} );
	setup_tooltip( $( 'li.myjobslink' ), 'Job Saved!', {'trigger':'none'} );
}

function init()
{
	setup_mylinks();

	$( '#passlink' ).bind( 'click', showRequestPassword );
	$( '.logoutlink' ).bind( 'click', setup_mylinks );
	$( '#passform button' ).unbind().bind( 'click', function( event ){ doRequestPassword( this.form, event ) });
  $( '.contactform button, .emailform button' ).bind( 'click', function(event){
      call_ajax({
    		'url' : this.form.action,
    		'method' : 'post',
    		'form' : $( this.form ),
    		'success_callback' : function( result ){
    		  	show_message( $( this.form ), result.message );
    		  },
    		'failure_callback' : function( result ){
    		    show_message( $( this.form ), result.message );
        }
    	});

    	return false;
  } );

	$( 'input[type="text"], input[type="password"], textarea, select' ).bind( 'focus', function( event ){ $(this).parent( '.form-item' ).addClass( 'input' );$(this).select() } );
	$( 'input[type="text"], input[type="password"], textarea, select' ).bind( 'blur', function( event ){ $(this).parent( '.form-item' ).removeClass( 'input' ); } );
	
	$( '#locations .alphabar li a' ).unbind().bind( 'click', function( even ){ get_group( this.text, '<li><a href="search.php?where={ESCAPEDITEM}">{ITEM} <span>({COUNT})</span></a></li>' ) });
	$( '#companies .alphabar li a' ).unbind().bind( 'click', function( even ){ get_group( this.text, '<li><a href="/jobs/?as_company={ESCAPEDITEM}">{ITEM} <span>({COUNT})</span></a></li>' ) });	

  //$( '.resume .replacelink' ).bind( 'click', function(event){alert('Replace');return false} );
  //$( '.resume .removelink' ).bind( 'click', function(event){alert('Remove');return false} );
  
  $( '.clearform' ).bind( 'click', function(event){ $(this).parents('form').reset();return false; } );
  
  $( '.frm :text:first' ).focus();
  $( '#home :text:first' ).focus();
}

function alert_jobalert_add()
{
  $( 'li.myalertslink' ).effect( 'highlight', {}, 3000 ).btOn();
  setTimeout(function(){$( 'li.myalertslink' ).btOff()}, 3000);
}

function alert_job_saved()
{
  $( 'li.myjobslink' ).effect( 'highlight', {}, 3000 ).btOn();
  setTimeout(function(){$( 'li.myjobslink' ).btOff()}, 3000);
}

function setup_tooltip( element, message, properties )
{ 
  if ( !element ) return;
  
  var props = {
    fill: 'black',
    closeWhenOthersOpen: true,
    cssStyles: {'color': 'white', 'fontWeight': 'bold'},
    shrinkToFit: true,
    showTip: function(box){
        $(box).fadeIn(500);
      },
      hideTip: function(box, callback){
        $(box).animate({opacity: 0}, 500, callback);
      },
    padding: 10,
    cornerRadius: 10,
    spikeLength: 15,
    spikeGirth: 15,
    positions: ['bottom'],
    hoverIntentOpts: {
      interval: 0,
      timeout: 400
    }};
  
  if ( properties ) 
  {
    for(var pname in properties) 
    {
      props[pname] = properties[pname];
    }
  }
  
  if ( message && message !== '' ) 
  {
    $( element ).bt( message, props );
  }
  else
  {
    $( element ).bt( props );
  }
}

function show_message( form, message )
{
  $( form ).find( '.errormessage' ).html( '<p>'+message+'</p>' ).show( "highlight", {}, 3000 ).fadeOut( "slow" );
}

function is_loggedin()
{
	return $( '#welcome_message_name' ).length > 0;
}

function get_group( alpha, template )
{
	call_ajax({
			'url' : window.location.href + '?ajax=1&g=' + alpha,
			'method' : 'get',
			'success_callback' : function( data ){
			  var items = build_list( data, 'alllist', template );
        $( 'ul.alllist' ).replaceWith( items );
      }
		});
	return false;
}

function login_action( event )
{
	call_ajax({
			'url' : '/login/',
			'form' : $( '#loginform' ),
			'method' : 'post',
			'redirect_url' : event.data,
			'success_callback' : login_success,
			'before_callback' : before_login
		});
  
	return false;
}

function build_list ( data, cssClass, template )
{
  var items = '<ul class="' + cssClass + '">';

  for( var i = 0; i < data.items.length; i++ )
  {
    items += template.replace( '{ESCAPEDITEM}', data.items[i][0] ).replace( '{ITEM}', data.items[i][1] ).replace( '{COUNT}', data.items[i][4] );
  }
  
  items += '</ul>';
  
  return items; 
}

function load_locations()
{ 
	call_ajax({
	    'method' : 'get',
			'url' : '/locationsajax.php',
			'success_callback' : display_locations
		});
}

function load_companies()
{ 
	call_ajax({
	    'method' : 'get',
			'url' : '/companiesajax.php',
			'success_callback' : display_companies
		});
}

function get_locations( event )
{ 
	call_ajax({
	    'method' : 'get',
			'url' : this,
			'success_callback' : display_locations
		});
	return false;
}

function get_companies( event )
{ 
	call_ajax({
	    'method' : 'get',
			'url' : this,
			'success_callback' : display_companies
		});
	return false;
}

function display_locations( data )
{
  var items = build_list( data, 'catlist', '<li><a href="search.php?where={ESCAPEDITEM}">{ITEM} <span>({COUNT})</span></a></li>' );
  
  $( 'div.tabs > div#second ul.catlist' ).replaceWith( items );
}

function display_companies( data )
{
  var items = build_list( data, 'catlist', '<li><a href="search.php?as_company={ESCAPEDITEM}">{ITEM} <span>({COUNT})</span></a></li>' );

  $( 'div.tabs > div#third ul.catlist' ).replaceWith( items );
}

function newspaperize(elem)
{
    var cnt = 8; 
    var items = $(elem).children().remove('a');
    var p = $(elem).parent();
    
    var holder = [];
    var col1 = "<ul class='catlist'>";
    var col2 = "<ul class='catlist'>";
    var col3 = "<ul class='catlist'>";
    var col4 = "<ul class='catlist'>";
    
    holder[0] = [];
    holder[1] = [];
    holder[2] = [];
    holder[3] = [];
    
    $(elem).remove();

    for ( var i = 0; i < items.length; i++ )
    {
      var idx = Math.floor(i/8);
      var line = "<li>" + items[i].innerHTML + "</li>";
      
      switch ( idx )
      {
        case 0 :
          col1 += line;
          break;
          
        case 1 :
          col2 += line;
          break;
          
        case 2 :
          col3 += line;
          break;
          
        case 3 :
          col4 += line;
          break;
      }
    }
    
    col1 += "</ul>";
    col2 += "</ul>";
    col3 += "</ul>";
    col4 += "</ul>";
    
    p.append(col1);
    p.append(col2);
    p.append(col3);
    p.append(col4);
}

function roundedRect(ctx,x,y,width,height,radius)
{
  ctx.beginPath();
  ctx.moveTo(x,y+radius);
  ctx.lineTo(x,y+height-radius);
  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
  ctx.lineTo(x+width-radius,y+height);
  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
  ctx.lineTo(x+width,y+radius);
  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
  ctx.lineTo(x+radius,y);
  ctx.quadraticCurveTo(x,y,x,y+radius);
  ctx.stroke();
}


$(document).ready(init);