// The "module" exported by this script is called "nglink":

var littleIconsHover = true;
//hover link functions
$(document).ready(function(){
  
  //This is where the little link icons appear when an Admin user hovers
  //over a link
  $('.sortable-link').live('mouseover', function(){ //mouseenter
    // note: these little icons (.link-actions) are positioned absolute
    // relative to the span.bundle-container
    //first hide all open link actions
    if (littleIconsHover == false) { return; }
    $('.link-actions, .bundle-actions').hide();
    var thisLinkActions = $(this).find('.link-actions');

    if ($(this).parents('.sidebar.bundle').length > 0) {
      linkTop = ($(this).position().top - 0) + "px";
      thisLinkActions.show().css('top', linkTop);
      linkLeft = ($(this).position().left - 18 ) + "px";
      thisLinkActions.show().css('left', linkLeft);
    }

    if ($(this).parents('.footer.bundle').length > 0) {
      linkLeft = ($(this).position().left ) + "px";
      thisLinkActions.show().css('left', linkLeft);
      linkTop = ($(this).position().top + $(this).height() + 5) + "px";
      thisLinkActions.show().css('top', linkTop);
    }

    if ($(this).parents('.header.bundle').length > 0) {
      linkLeft = ($(this).position().left + 10 ) + "px";
      thisLinkActions.show().css('left', linkLeft);
      linkTop = ($(this).position().top - 5) + "px";
      thisLinkActions.show().css('top', linkTop);
    }

    $(this).parents('.sortable-bundle').find('.bundle-actions').hide();
  }).live('mouseout',function(){ //mouseleave
    var that = this;
    var t = setTimeout(function(){
      $(that).find('.link-actions').animate({'opacity': '0'}, "fast", function(){
        $(this).css('display', 'none');
        $(this).css('opacity', '1');
      })

      //$(that).find('.link-actions').fadeOut('slow', function(){
      //  clog($(that).find('.link-actions').css('display'));
      //})

    }, 500)
    function linkActionAMouseOver(e){
      clearTimeout(t);
      $(this).unbind('mouseover', linkActionAMouseOver) //unbind yourself.
    }
    function linkMouseOver(e) {
      clearTimeout(t);
      $(this).unbind('mouseover', linkMouseOver);
    }
    $(this).mouseover(linkMouseOver);
    $(this).find('.link-actions a').mouseover(linkActionAMouseOver);    
    // $(this).parents('.sortable-bundle').find('.bundle-actions').show();
  })
    
    //This is so the liitle orage box goes over the pencil icon, the trash icon and the move-arrow icon.
    $('.link-actions a')
      .live('mouseover', function(){$(this).addClass('ui-state-hover')})
      .live('mouseout', function(){$(this).removeClass('ui-state-hover')});
    
    //This is for the Edit Link Dialog (aka Update Link) Dialog.
    //It is so that the internal and exteral links are shown and hid depending on what radio
    //button is pressed
    $('.edit-link-dialog #link_type_internal').live('click',function(e){
      $('.edit-link-dialog #external').hide();
      $('.edit-link-dialog #internal').show();
    })
    
    $('.edit-link-dialog #link_type_external').live('click',function(e){
      $('.edit-link-dialog #internal').hide();
      $('.edit-link-dialog #external').show();
    })
    
    $('.new-link-dialog #link_type_internal').live('click',function(e){
      $('.new-link-dialog #external').hide();
      $('.new-link-dialog #internal').show();
    })
    
    $('.new-link-dialog #link_type_external').live('click',function(e){
      $('.new-link-dialog #internal').hide();
      $('.new-link-dialog #external').show();
    })
    //Firefox wasn't cooperating with `checked="checked"` so I had to manually check the internal link radio
    //for the edit link dialog
    $('.edit-link-dialog #link_type_internal, .new-link-dialog #link_type_internal').click();
        
    //deleting a link
    $('.link-actions .ui-icon-trash').live('click', function(){
        var link = $(this).parents('.sortable-link').find('a.link-click')
        var link_rel = link.attr('rel').split('index.html');
        var link_id = link_rel[link_rel.length - 1];
        $.ajax({
          'type' : 'POST',
          'url' : link.attr('rel'),
          'data' : {
              '_method' : "DELETE",
              "authenticity_token" : form_authenticity_token
          },
          'success' : function(result) {
              //remove the actual link
              link.parents('.sortable-link').fadeOut('fast',function(){$(this).remove()});
            } //end success function
        }) //end ajax
         return false;
    }) //end when you click on the trash link
    
    
    //edit a link //edit link
    $('.link-actions .ui-icon-pencil').live('click', function(){
      var link = $(this).parents('.sortable-link').find('a.link-click');
      var link_rel = link.attr('rel').split('index.html');
      var link_id = link_rel[link_rel.length - 1];
      var link_bundle_id = link.parents('.bundle-container').find('a.data').attr('id');
      
      //set the text of the text box to be the text of the link
      $(".edit-link-dialog .link-display-text").val(link.text());
      var new_dialog = $(".edit-link-dialog:eq(0)"); //why is the other one cloning it? //bundle.js
      
      var form = $(new_dialog).find(".edit-link-form");
      
      function formSubmit(){
        clickOk.call(new_dialog) //calling clickOk with *this* as the dialog
        form.unbind('submit',formSubmit)
        return false;
      }
        
      form.submit(formSubmit)
      
      function clickOk() {
            form.find("[name='authenticity_token']").val(form_authenticity_token);
            form.find("[name='link[bundle_id]']").val(link_bundle_id);
            form.attr('action', '/links/' + link_id + ".js")
            
            ret = {} //ret will hold all the post values
            form.find('[name]').each(function(){
              if ($(this).is('[type="radio"]')) { //handle the radio buttons with more care.
                var the_name = $(this).attr('name');
                ret[the_name] = form.find('[name="'+the_name+'"]:checked').val() 
              } else {
                ret[$(this).attr('name')] = $(this).val();
              }
            })
            clog(ret)
            
            $.ajax({
              'type' : 'POST',
              'url' : form.attr('action'),
              'data' : ret,
              'success' : function(result) {
                result = JSON.parse(result)
                clog(result)
                var display_text = result.link.display_text
                link.text(display_text)
                link.attr('href', result.link.url)
              }
            })

            $(this).dialog("close");
            $(this).dialog("destroy"); //if you don't destroy it, the still-bound handlers with come back to haunt you.
          }
      
      new_dialog.dialog({
        bgiframe: true,
        autoOpen: false,
        height: 300,
        width: 350,
        modal: true,
        buttons: {
          "Ok": clickOk,
          "Cancel": function() {
            $(this).dialog("close");
            $(this).dialog("destroy");
          }
        }
      })
      new_dialog.dialog("open");
    
      return false;
    })
    
    
    
})





var nglink = function() {

function Link(link_list) {
  
  if(!(this instanceof Link)) {
    return new Link(link_list);
  }
  
  this._link_list = link_list;
  this._link_handle_selector = ".link-handle"
  this._link_sortable_selector = ".sortable-link"; // our bundle "object"

  clog("Link setup");
  clog(this._link_list);
}

/* Creates a POST to /links/id/move. The display_order is the destination */
Link.prototype.move_link = function(link, bundle, idx_dest) {
  clog("Moving link");
  // clog("In Bundle: " + stopBundle.find("a.data").siblings().html());
  // clog("At index: "  + stopLinkAt);
  // clog(link);

  var bundle_id = bundleId(bundle);
  var display_order = idx_dest + 1;
  var data = link.find("a");
  var rel = data.attr("rel");
  var url = rel + "/move";
  clog("Moving link " + rel + " to bundle: " + bundle_id + " at " + display_order);

  jQuery.post(url, {
     "_method": "post",
     "authenticity_token": form_authenticity_token,
     "display_order": display_order,
     "bundle_id": bundle_id
   },
   function(data, status){
     // clog("Moved link");
     // clog(data);
   });
   
   
};

//makes a link sortable 
//jq is the jquery selector
//this wrapper is to preserve scope of self.
function makeSortableMaker(self) {
  function makeSortable(jq) {
    jq.sortable({
      items: self._bundle_sortable_selector,
      placeholder: 'ui-state-highlight',
      handle: self._bundle_handle_selector,
      cursor: "move",
      revert: true,
      connectWith: '.link-list',
      dropOnEmpty: 'true',
      start: function(event, ui) {
        $('.link-actions').hide() //hide all the link actions while moving
        littleIconsHover = false; //linkIconsHover is a flag that says wether or not the links appear.
        startAt = endAt = linkAt(self._link_list, ui.item);
        autofit(ui.placeholder, ui.item);
      },
      
      stop: function(event, ui) {
        littleIconsHover = true;
        // endAt = linkAt(self._link_list, ui.item);
        endAt = ui.item.parent().children().index(ui.item[0])
        
        clog(endAt)
        var oldBundle = $(this).parents('.bundle-container')
        var oldBundleId = oldBundle.find('a.data').attr('id')
        var newBundle = $(ui.item).parents('.bundle-container')
        var newBundleId = newBundle.find('a.data').attr('id')
        if (!(oldBundleId == newBundleId && startAt == endAt)) { //don't call move_link if you are moving to the same position
          //self.move_link(ui.item, endAt);
          //clog("here is the bundle...")
          //clog($(this))
          //clog("end bundle")
          //clog("new bundle is")
          //clog(newBundle)
          // Subtracting 1 from the endAt index if the link is in the header or the footer
          // This accommodates for the "+" link that is put as the first <li> of the 
          // header and footer
          if (newBundle.parents(".header.bundle").length) {
            endAt = endAt - 1;
          }
          if (newBundle.parents(".footer.bundle").length) {
            endAt = endAt - 1;
          }
          self.move_link(ui.item, newBundle, endAt)
        }
      }
    });
  }
  return makeSortable;
}


Link.prototype.enableSorting = function() {
  var self = this;
  var startAt, endAt = null;
  var makeSortable = makeSortableMaker(this);
  Link.prototype.makeSortable = makeSortable
  makeSortable(this._link_list)
};

Link.prototype.enableMenus = function() {
  var self = this;
  var startLinkAt, stopLinkAt, startBundle, stopBundle, startLinkList, stopLinkList = null;


  // Set cursor via JS since I can't seem to set the cursor in a stylesheet. 
  jQuery(this._link_list.find(this._link_handle_selector)).css("cursor", "move");

  this._link_list.sortable({
    connectWith: '.connected-links',
    items: this._link_sortable_selector,
    placeholder: 'ui-state-highlight',
    handle: this._link_handle_selector,
    cursor: "move",
    revert: true,

    start: function(event, ui) {
      startLinkList = stopLinkList = linkList(ui.item);
      startLinkAt = stopLinkAt = linkAt(startLinkList, ui.item);
      startBundle = stopBundle = bundleOf(ui.item);
      autofit(ui.placeholder, ui.item);
    },

    stop: function(event, ui) {
      stopLinkList = linkList(ui.item);
      stopLinkAt = linkAt(stopLinkList, ui.item);
      stopBundle = bundleOf(ui.item);

      // dispatch call only when the UI changes
      if (!(startLinkAt === stopLinkAt && bundleId(startBundle) === bundleId(stopBundle))) {
        self.move(ui.item, stopBundle, stopLinkAt);
      }
    }

    // stop: function(event, ui) {
      // clog("stop");
// Over from: " + startBundle.find("a.data").siblings().html() + " to " + 
      // clog("start: " + startLinkAt + " stop: " + stopLinkAt);
      // clog([startBundle, stopBundle]);
      // if (startLinkAt != stopLinkAt) {
      //   clog("Moved link");
      // }
      // clog("Moving:");
      // clog(startLink);
      // clog(startBundle);
      // clog(stopBundle);
    // }

  });
};

Link.prototype.setup = function() {
  this.enableSorting();
  this.enableMenus();
  // this.enableActions();
  this._link_list.disableSelection();
};

/* Autofits the placeholder to the height&width of the item */
function autofit(placeholder, item) {
  jQuery(placeholder).height(item.outerHeight(true)).width(item.outerWidth(true));
}

/* Returns the position of the link within the list */
function linkAt(link_list, sortable_link) {
  return link_list.children().index(sortable_link);
}

/* Returns the bundle DOM obj */
function bundleOf(sortable_link) {
  return sortable_link.parent().parent().parent();
}

/* Returns the link-list */
function linkList(sortable_link) {
  return bundleOf(sortable_link).find("ul.ui-sortable.link-list");
}

function bundleId(sortable_bundle) {
  return sortable_bundle.find("a.data").attr("id");
}

// function bundleAt(sortable_link) {
//   return sortable_link.parent().parent().find("a.data");
// }

// function getBundle(sortable_link) {
//   clog(sortable_link.parent().parent().find("a.data").siblings().html());
//   return sortable_link.parent().parent().find("a.data");
// }

function logBundle(ui) {
  clog(ui);
  clog("Helper: ");
  clog(ui.helper);
  clog("Position: ");
  clog(ui.position);
  clog("Offset: ");
  clog(ui.offset);
  clog("Item: ");
  clog(ui.item);
  clog("PlaceHolder: ");
  clog(ui.placeholder);
  clog("Sender: ");
  clog(ui.sender);
}

return {Link: Link};

}();