function reset_row_classes()
{
   var odd = true;
   var $rows = $(".grid").find("tr:even, tr:odd");
   var $not_hidden = $rows.filter(":not(:hidden)");
   
   $not_hidden.each(function() {
	   if (odd && $(this).hasClass("even")) {
		   $(this).removeClass("even");
		   $(this).addClass("odd");
	   }
	   if (!(odd) && $(this).hasClass("odd")) {
		   $(this).removeClass("odd");
		   $(this).addClass("even");
	   }
	   odd = !(odd);
   });
}

function hide_prog($prog) {
    if ($prog.hasClass("main_view")) {
        // Fade out then slide the other elements along
        $prog.animate({opacity: 0}, 500, function() { 
        	$prog.animate({width: 0, padding: 0}, 500);
        });    	
    } else {
    	$prog.fadeOut(500, function() { 
    		if (type != "block") {
    			$prog.removeClass("shown");
    			
    			// If this was the first episode from a programme, the next one needs to take over as a master
    			set_toggles();
    		} 
        	// Reset the odd/even classes on the table rows
    		reset_row_classes(); 
    	});
    }	
}

function show_prog($prog) {
    if ($prog.hasClass("main_view")) {
    	$prog.animate({width: 170, padding: '10px 10px 0 0'}, 500, function() {
    		$prog.animate({opacity: 1}, 500);
    	});    	
    } else {
    	$prog.fadeIn(500, function() { 
    		if (type != "block") {
    			$prog.addClass("shown");
    			set_toggles();
    		} 
        	// Reset the odd/even classes on the table rows
    		reset_row_classes(); 
    	});
    }
}

function set_classes(anchor, condition, true_class, false_class)
{
    if (condition)
    {
  	  $(anchor).removeClass(false_class);
  	  $(anchor).addClass(true_class);
    }
    else
    {
  	  $(anchor).removeClass(true_class);
  	  $(anchor).addClass(false_class);
    }
}

function remove_row(anchor, undo_url, undo_string, type)
{
    // Hide the tooltip just in case it's still hanging around
    $("#tooltip").css("display", "none");	
	
    var $prog = $(anchor).closest('.prog');
    
    // If this is the master row of a set, make the next row the master
    if ($prog.hasClass("master")) {
    	if ($prog.find(".pg_toggle").hasClass("pg_toggle_open")) {
    		var $next_prog = $prog.next();
    		$next_prog.addClass("master");
    		$next_prog.find(".pg_toggle").addClass("pg_toggle_open");
    		$next_prog.find(".pg_name").removeClass("hidden");
    	}	
    	if ($prog.find(".pg_toggle").hasClass("pg_toggle_closed")) {
    		var $next_prog = $prog.next();
    		if (! $next_prog.hasClass("master")) {
        		$next_prog.addClass("master");
        		$next_prog.find(".pg_toggle").addClass("pg_toggle_closed");
        		$next_prog.find(".pg_name").removeClass("hidden");
        		$next_prog.fadeIn(500, function() {
        			if (type != "block") {
        				$prog.addClass("shown");
        			}
        		});    			
    		}
    	}	
    }
    
    // Identify this as the programme we'll restore if the user presses undo
    $('#undo_prog').removeAttr('id');
    $('#undo_control').removeAttr('id');
    $prog.attr('id', 'undo_prog');
    $(anchor).attr('id', 'undo_control');
    
    hide_prog($prog);
    
    // Update the undo
    var $u = $('#undo');
    var item_id = $prog.attr('item_id');
    var item_name = $prog.attr('item_name');    	
    $u.removeClass('off');
    $u.attr({'title': undo_string, 
    	     'href': undo_url,
    	     'onclick': 'return do_undo(event, this);',
    	     'item_id': item_id,
    	     'item_name': item_name,
    	     'type': type});
}

function do_undo(event, anchor) {
	$(anchor).addClass("off");
	$(anchor).attr('title', 'Nothing to undo');
	$(anchor).removeAttr('onclick');
	var url = $(anchor).attr('href');
	var item_id = $(anchor).attr('item_id');
	var item_name = $(anchor).attr('item_name');
	var type = $(anchor).attr('type');
	var $prog = $("#undo_prog");
	var $control = $prog.find('#undo_control');
	$prog.removeAttr('id');
	$control.removeAttr('id');
	$(anchor).removeAttr('href');

	switch (type) {
		case "block" : 	
			block_program(event, $control, item_name, item_id, false, false);
			break;
		case "seen" : 
			seen_episode(event, $control, item_name, item_id, false, false);
			break;
		case "watchlist" : 
			watchlist_episode(event, $control, item_name, item_id, false, false);
			break;
	}

	show_prog($prog);	
}

function ajax_control(event, url, id, success_function, reload_progbox) {
   event.stopPropagation(); 
   event.preventDefault();
	  	
   $.ajax({url: url,
           cache: true,
           data: {id: id, json: true},
           success: success_function,
           error: function(XMLHttpRequest, textStatus, errorThrown) {
              alert(textStatus + errorThrown);
           },           
           complete: function(response, textStatus) {
               if (response.status == 302) {
                   window.location = response.getResponseHeader('Location');
               };
               if (reload_progbox) {
            	   // This should only be happening if the item that id refers to is a programme
            	   url = 'show_progbox?' + $.param({'pg_id' : id})
            	   $('#prog_box').load(url); 
               };
           }});
}

function block_program(event, anchor, pg_name, pg_id, remove_on_block, reload_progbox)
{
  return block_item(event, anchor, pg_name, pg_id, "programme", remove_on_block, reload_progbox);
}

function block_cat(event, anchor, cat_name, cat_id)
{
   return block_item(event, anchor, cat_name, cat_id, "category", false, false);
}

function block_chan(event, anchor, chan_name, chan_id)
{
   return block_item(event, anchor, chan_name, chan_id, "channel", false, false);
}

function item_blocked(name, id, anchor, block, type, remove_on_block)
{
    if (type == 'programme') 
    {
    	set_classes(anchor, block, 'prog_blocked', 'prog_unblocked');
    	if (block) {
    		// It will be unfavourited as well 
    		var $fav_control = $(anchor).closest(".prog").find(".favourite");
    		$fav_control.removeClass("fav");
    		$fav_control.addClass("notfav");
    	}
    }
    else
    {
    	set_classes(anchor, block, 'blocked', 'unblocked');
    }
    anchor.title= (block ? "Add back into your list" : "Not interested");

    // If there is an associated text string (as in the programme page listing the episodes) we need to change that too 
    if ($(anchor).html())       
    {    
        $(anchor).html(block ? "This is a programme you're not interested in" : "");
    }    
    
   if (block) {
	   if ((remove_on_block) || (remove_on_block == 'True')) {
	      // Build an undo url.  We only use this when we're blocking so the undo URL is always an unblock
	      var url = '/' + type + '/';
	      if (type == 'programme')
	      {
	           url = '/';
	      }
	      url = url + 'unblock?id=' + id;
	      var undo_string =  "Undo - Restore " + name;
	
	      // Remove the row for this item
	      remove_row(anchor, url, undo_string, "block");
	   }
   }
}

function block_item(event, anchor, name, id, type, remove_on_block, reload_progbox)
{
   var block = true;
   if (($(anchor).hasClass('blocked')) || ($(anchor).hasClass('prog_blocked'))) {
      block = false;
   }
   
   var url = '/' + type + '/';
   if (type == 'programme') {
      url = '/';
   }
   
   var success_function = reload_progbox ? function(msg) {} : function(msg)  { item_blocked(name, id, anchor, block, type, remove_on_block); };
   var block_url = url + (block ? 'block' : 'unblock');

   ajax_control(event, block_url, id, success_function, reload_progbox);
   
   return false;
}

function program_favourite(pg_name, pg_id, anchor, make_fav)
{
	set_classes(anchor, make_fav, 'favourite', 'notfav');
	anchor.title = make_fav ? "Mark as not a favourite" : "Mark as favourite";
    
	// If there is an associated text string (as in the programme page listing the episodes) we need to change that too 
    if ($(anchor).html())       
    {    
        $(anchor).html(make_fav ? "This is one of your favourites " : "This isn't one of your favourites ");
    }    	
}

function favourite_program(event, anchor, pg_name, pg_id, reload_progbox)
{
   var make_fav = true;
   if ($(anchor).hasClass('favourite')) {
      make_fav = false;
   }
   
   var success_function = reload_progbox ? function(msg) {} : function(msg)  { program_favourite(pg_name, pg_id, anchor, make_fav); };
   var url = make_fav ? '/favourite' : '/unfavourite';
   
   ajax_control(event, url, pg_id, success_function, reload_progbox);

	// There could be text for telling the user this automatically adds episodes to their watchlist
	$(".on_favourite").toggle();

   return false;

}

function program_watchlist(pg_name, pg_id, anchor, add_to_watchlist)
{
   set_classes(anchor, add_to_watchlist, 'watchlisted', 'notwatchlisted');
   anchor.title = add_to_watchlist ? "Remove from your watchlist" : "Add to your watchlist";
    
   // If there is an associated text string (as in the programme page listing the episodes) we need to change that too 
   if ($(anchor).html())       
   {    
       $(anchor).html(add_to_watchlist ? "This is in your watchlist" : "This is not in your watchlist");
   }    	
}

function watchlist_program(event, anchor, pg_name, pg_id, reload_progbox)
{
   var add_to_watchlist = true;
   if ($(anchor).hasClass('watchlisted')) {
      add_to_watchlist = false;
   }

   var success_function = reload_progbox ? function(msg) {} : function(msg)  { program_watchlist(pg_name, pg_id, anchor, add_to_watchlist); };
   var url = add_to_watchlist ? '/programme_watchlist' : '/programme_unwatchlist';
   
   ajax_control(event, url, pg_id, success_function, reload_progbox);

   return false;
}

function myPopupRelocate(thispopup)
{
    var scrolledX, scrolledY;
    var $popup = $('#'+thispopup);
    if( self.pageYOffset )
    {
        scrolledX = self.pageXOffset;
        scrolledY = self.pageYOffset;
    }
    else if( document.documentElement && document.documentElement.scrollTop )
    {
        scrolledX = document.documentElement.scrollLeft;
        scrolledY = document.documentElement.scrollTop;
    }
    else if( document.body )
    {
        scrolledX = document.body.scrollLeft;
        scrolledY = document.body.scrollTop;
    }

    var centerX, centerY;
    if( self.innerHeight )
    {
        centerX = self.innerWidth;
        centerY = self.innerHeight;
    }
    else if( document.documentElement && document.documentElement.clientHeight )
    {
        centerX = document.documentElement.clientWidth;
        centerY = document.documentElement.clientHeight;
    }
    else if( document.body )
    {
        centerX = document.body.clientWidth;
        centerY = document.body.clientHeight;
    }

    var leftOffset = scrolledX + (centerX - $popup.width()) / 2;
    var topOffset = scrolledY + (centerY - 200) / 2;

    $popup.offset({top: topOffset, left: leftOffset});
}

function raise_popup(event, thispopup)
{
    event.stopPropagation(); 
    event.preventDefault();

    myPopupRelocate(thispopup);
    var this_name = "#" + thispopup;
    
    $("#ttlightbox").height($(document).height());
    $("#ttlightbox").width($(document).width());
    $("#ttlightbox").attr('onClick',"hide_popup(event, '" + thispopup + "');");
    $("#ttlightbox").show();
    $(this_name).show();
    
    document.body.onscroll = myPopupRelocate(thispopup);
    window.onscroll = myPopupRelocate(thispopup);
    return false;
}

function hide_popup(event, thispopup) {
    event.stopPropagation(); 
    event.preventDefault();
    var this_name = "#" + thispopup;
    $(this_name).hide();
    $("#ttlightbox").hide();
}


function account_needed(event)
{	
	raise_popup(event, "mypopup")
}

function linked_account_needed(event)
{	
	raise_popup(event, "link_popup")
}

function episode_seen(ep_name, ep_id, anchor, make_seen, remove_on_seen)
{
	set_classes(anchor, make_seen, 'seen', 'unseen');
    anchor.title = make_seen ? "Mark as not seen" : "Mark as seen";
    
    if (remove_on_seen)
    {
        // Build an undo url
        var url = '/unseen?id=' + ep_id;
        var undo_string =  "Undo - I haven't seen " + ep_name + " yet"
    	
 	    remove_row(anchor, url, undo_string, "seen"); 
    }
}

function episode_watchlist(ep_name, ep_id, anchor, add_to_watchlist, remove_on_unwatchlisted)
{
	set_classes(anchor, add_to_watchlist, 'watchlisted', 'unwatchlisted');
    anchor.title = add_to_watchlist ? "Remove from watchlist" : "Add to watchlist";

    if (remove_on_unwatchlisted)
    {
        // Build an undo url
        var url = '/watchlist?id=' + ep_id;
        var undo_string =  "Undo - Add " + ep_name + " back into my watchlist"
    	
 	    remove_row(anchor, url, undo_string, "watchlist"); 
    }
}

function seen_episode(event, anchor, ep_name, ep_id, remove_on_seen)
{
   var make_seen = true;
   if ($(anchor).hasClass('seen')) {
      make_seen = false;
   }

   var success_function = function(msg) { episode_seen(ep_name, ep_id, anchor, make_seen, remove_on_seen); };
   var url = make_seen ? '/seen' : '/unseen';
   
   ajax_control(event, url, ep_id, success_function, false);
}

function watchlist_episode(event, anchor, ep_name, ep_id, remove_on_unwatchlist)
{
   var add_to_watchlist = true;
   if ($(anchor).hasClass('watchlisted')) {
      add_to_watchlist = false;
   }

   var success_function = function(msg) { episode_watchlist(ep_name, ep_id, anchor, add_to_watchlist, remove_on_unwatchlist); };
   var url = add_to_watchlist ? '/watchlist' : '/unwatchlist';
   
   ajax_control(event, url, ep_id, success_function, false);
   
   return false;
}

function build_category(pg_id, id, name)
{
   return $('<span><a href="/show_in_cat?category=' + name + '&id='+ id + '">' +
            name + '</a><a class="cat_remove" href="/category/remove?id='+id+'&pg_id='+pg_id+
            '"><img src="/static/images/cross.png"/></a></span>');
}


// For the account form, display and hide details about Facebook and Twitter according to whether they're enabled
function enable_checkbox_click(event)
{
  enable_checkbox_state($(this), "fast")
}

function enable_checkbox_state(checkbox, duration)
{
  if (checkbox.is(":checked"))
  {
    checkbox.closest("form").find(".account_fieldset").fadeIn(duration);
    checkbox.closest("form").find(".account_fieldset").closest("tr").find("label").fadeIn(duration);
  }
  else
  {     
    checkbox.closest("form").find(".account_fieldset").fadeOut(duration);
    checkbox.closest("form").find(".account_fieldset").closest("tr").find("label").fadeOut(duration);
  }
  
}

function initialize_checkboxes() {
    
    // Initialize the fields
    $(".enable_checkbox").each(function(i){
                               enable_checkbox_state($(this), 0)})              
                  
    $(".enable_checkbox").click(enable_checkbox_click)
}

(function( $ ) {
	$.fn.match_height = function( options ) {

		var settings = $.extend( {
			match : "#content"
		}, options);		

		var $match_from = $(this);
		var $match_to = $(settings.match);
		
		var other_height = $match_to.height();
		var this_height = $match_from.height();
		if (other_height > this_height) {
			$match_from.height(other_height);
		} else {
			$match_to.height(this_height);
		}			
	};	
	
})( jQuery );
