var TvGrid = $.klass({
  
  initialize: function(element, options)
    {
    this.options = $.extend({
      hour_width:  250,
      min_size: 100,
      channel_width: 84,
      cursor_width: 20
      }, options);
    this.grid = $(element);
    this.channels = this.grid.find("ul.channels");
    
    this.broadcasts = [];
    this.initialize_grid();
    this.toggle_empty_message();
    
    this.cursor = new TvCursor(this.options);
    
    $("#add_channels div.list").click(function(e){
      e.stopPropagation();
      });
    
    $(document.body).bind("click", this, function(e){
      if($("#add_channels div.list").is(":visible")) e.data.toggle_new_channels.apply(e.data, [e]);
      });
    },
  
  initialize_grid: function()
    {
    var obj = this;
    
    this.initialize_filters();
    
    $("#displayed_channels").sortable({
      axis: "y",
      update: function(event, ui)
        {
        obj.save_session();
        if(Nav.is_logged_in() == false) Nav.teaser.link.trigger("click");
        }
      });
    $("#displayed_channels").disableSelection();
    
    this.initialize_lines(this.channels);
    
    $("#add_channels p.button a").bind("click", this, function(e){
      e.data.toggle_new_channels.apply(e.data, [e]);
      });
    $("#add_channels p.button input").bind("click", this, function(e){
      e.data.save_grid.apply(e.data, [e]);
      });
    $("#add_channels div.list").hide().removeClass("hidden");
    this.initialize_add_channels($("#add_channels div.list li"));
    
    $(document.body).append('<div id="broadcast_popup"></div>');
    $("#broadcast_popup").hide().bind("mouseleave", this, function(e){
      e.stopPropagation();
      e.data.close_broadcast_popup.apply(e.data, [e]);
      });
    },
  
  initialize_add_channels: function(collection)
    {
    collection.bind("mouseenter", this, function(e){
      var target = ($(e.target).attr("nodeName").toLowerCase() == "li")? $(e.target) : $(e.target).parent("li");
      $("#add_channels div.list li").removeClass("hover");
      target.addClass("hover");
      });

    collection.find("a").bind("click", this, function(e){
      e.data.add_channel.apply(e.data, [e]);
      });
    },
  
  initialize_lines: function(collection)
    {
    var obj = this;
    collection.find("li.wrapper a").each(function(){
      obj.broadcasts.push(new TvBroadcast(this,{
        grid: obj
        }));
      });
    
    collection.find("p.channel").prepend('<a class="delete" href="#">supprimer</a>');
    collection.find("p.channel a.delete").bind("click", this, function(e){
      e.data.delete_channel.apply(e.data, [e]);
      });
    
    var total_width = parseFloat($('#broadcasts ul.hours').width());
    var limit = total_width - (total_width / ((parseFloat($('#end').val()) - parseFloat($('#start').val())) * 60)) * 45;
    
    collection.find("li.wrapper").each(function(){
      var element = $(this);
      
      if(element.width() < obj.options.min_size || parseInt(element.css('left').replace('px', '')) >= limit)
        {
        var content = (element.find("div.broadcast").innerWidth() > 20)? "..." : "";
        element.append('<div class="broadcast_popup"></div>');
        element.find('div.broadcast_popup').hide().html(element.find("div.broadcast").html());
        element.find("div.broadcast").html(content);
        element.bind("mouseenter", obj, function(e){
          e.data.open_broadcast_popup.apply(e.data, [e]);
          });
        }
      else
        {
        element.bind("mouseenter", obj, function(e){
          e.data.close_broadcast_popup.apply(e.data, [e]);
          });
        }
      });
    },
  
  initialize_filters: function()
    {
    this.highlighted_classes = [];
    
    $("#filters ul.categories a").bind("click", this, function(e){
      e.data.highlight_broadcasts.apply(e.data, [e]);
      });
    },
  
  toggle_empty_message: function()
    {
    if($("#broadcasts li.line").length > 0) $("#empty").hide();
    else $("#empty").show();
    },
  
  open_broadcast_popup: function(e)
    {
    var target = ($(e.target).is("li.wrapper"))? $(e.target) : $(e.target).parent("li.wrapper");
    var popup = target.find("div.broadcast_popup");
    var position = target.offset();
    
    $("#broadcast_popup").html(popup.html()).css({ top: position.top, left: position.left-10 }).fadeIn();
    
    new TvBroadcast($("#broadcast_popup a"), { grid: this });
    },
  
  close_broadcast_popup: function(e)
    {
    $("#broadcast_popup").hide();
    },
  
  css_style_for: function(broadcast)
    {
    var style = "";
    
    style += "width:"+ this.broadcast_width(broadcast.length) + "px; ";
    style += "left:"+ this.broadcast_offset(broadcast.start) + "px;";
    
    return style;
    },
  
  broadcast_width: function(minutes)
    {
    return Math.round((parseInt(minutes) * this.options.hour_width) / 60);
    },
  
  broadcast_offset: function(offset)
    {
    return Math.round((parseInt(offset) * this.options.hour_width) / 60);
    },
  
  highlight_broadcasts: function(e)
    {
    e.preventDefault();
    var target = ($(e.target).attr("nodeName").toLowerCase() == "a")? $(e.target) : $(e.target).parent("a");
    
    var classname = target.attr("href").replace("#", "");
    
    if($.inArray(classname, this.highlighted_classes) == -1)
      {
      this.grid.find("div.broadcast." + classname).addClass("highlight");
      this.highlighted_classes.push(classname);
      }
    else
      {
      this.grid.find("div.broadcast." + classname).removeClass("highlight");
      this.highlighted_classes = $.map(this.highlighted_classes, function(value){
        return ((value == classname)? null : value);
        });
      }
    },
  
  delete_channel: function(e)
    {
    e.preventDefault();
    var line = $(e.target).parent("p").parent(".line");
    
    Nav.loading();
    line.remove();
    this.toggle_empty_message();
    
    var obj = this;
    
    $.ajax({
      url: $(e.target).attr("href"),
      type: "get",
      success: function(response)
        {
        Nav.check(response);
        var index = obj.index_for_channel($(response.html).find("a").text());
        $($("#add_channels div.list li")[index]).before(response.html);
        obj.initialize_add_channels($($("#add_channels div.list li")[index]));
        obj.save_session();
        }
      });
    
    if(Nav.is_logged_in() == false) Nav.teaser.link.trigger("click");
    },
  
  save_grid: function()
    {
    if(Nav.is_logged_in())
      {
      var data = $("#displayed_channels").sortable('serialize');
      Nav.loading();
      
      $.ajax({
        type: "post",
        url: Paths.root_url + Paths.save_grid,
        data: data,
        success: function(response){
          Nav.check(response);
          Nav.stop_loading();
          }
        });
      }
    else
      {
      Nav.teaser.link.trigger("click");
      }
    },
  
  save_session: function()
    {
    Nav.loading();
    
    var data = $("#displayed_channels").sortable('serialize');
    $.ajax({
      type: "post",
      url: Paths.root_url + Paths.save_session,
      data: data,
      success: function(response){
        Nav.check(response);
        Nav.stop_loading();
        }
      });
    },
  
  toggle_new_channels: function(e)
    {
    e.preventDefault();
    e.stopPropagation();
    
    var button = $("#add_channels p.button a");
    var position = button.position();
    
    $("#add_channels div.list").css({ top: (position.top + button.outerHeight()), left: position.left }).slideToggle({
      speed: 500
      });
    },
  
  add_channel: function(e)
    {
    e.stopPropagation();
    e.preventDefault();
    var target = ($(e.target).is("a"))? $(e.target) : $(e.target).parents("a");
    
    var obj = this;
    target.parents("li").addClass("loading");
    
    $.ajax({
      url: target.attr("href"),
      success: function(response)
        {
        Nav.check(response);
        $("#empty").hide();
        $("#displayed_channels").prepend(response.html);
        obj.initialize_lines($("#displayed_channels").find("li.line").first());
        target.parents("li").remove();
        obj.toggle_new_channels(e);
        obj.save_session();
        obj.cursor.move_cursor();
        if(Nav.is_logged_in() == false) Nav.teaser.link.trigger("click");
        }
      });
    },
  
  index_for_channel: function(name)
    {
    var values = [];
    $.each($("#add_channels .list li"), function(){
      values.push($(this).find("a").text());
      });
    values.push(name);
    values.sort();
    return $.inArray(name, values);
    }
  
  });
