var ProductPhotoCollection = new Class({
  initialize: function(product){
    this.photoWidth = 613;
    this.product = product;
    this.wrapper = $('.photo_wrapper', product.body);
    this.container = $('.photos', this.wrapper);
    this.images = $('img', this.container);
    this.nextLink = $('.photo_nav .right', this.wrapper).click(this.next.bind(this));
    this.prevLink = $('.photo_nav .left', this.wrapper).click(this.prev.bind(this));
    
    this.currentImageIndex = 0;
    this.reset();
  },
  
  hasImages: function(){
    return this.images.length > 0;
  },
  
  resetContainerHeight: function(){
    if (this.hasImages()) {
      var currentImageHeight = this.images[0].height;
      if (currentImageHeight > 0) {
        this.wrapper.height(currentImageHeight);
        this.container.height(currentImageHeight);
      };
    };
  },
  
  reset: function(){
    if (this.hasImages()) {
      this.container.css('left', '0px');
      this.currentImageIndex = 0;
      this.resetContainerHeight();
      this.resetNav();
    };
  },
  
  currentImage: function(){
    return $(this.images[this.currentImageIndex]);
  },
    
  nextImage: function(){
    var img = this.end() ? this.images[this.images.length - 1] : this.images[this.currentImageIndex + 1];
    return $(img);
  },
  
  prevImage: function(){
    var img = this.beginning() ? this.images[0] : this.images[this.currentImageIndex - 1];
    return $(img);
  },
  
  next: function(e){
    // Move the container one photo-width to the left
    if (e) {
      e.preventDefault();
      e.stopPropagation();
    };
    
    if (!this.end()) {
      this.wrapper.animate({
        height: this.nextImage().height()
      }, 300, function() {
        this.currentImageIndex += 1;
      }.bind(this));

      this.container.animate({
        left: (this.container.position().left - this.photoWidth) + 'px', 
        height: this.nextImage().height()
      }, 500, null, function() {
        this.resetNav();
      }.bind(this));
    };
  },
  
  prev: function(e){
    // Move the container one photo-width to the right
    if (e) {
      e.preventDefault();
      e.stopPropagation();
    };
    
    if (!this.beginning()) {
      this.wrapper.animate({
        height: this.prevImage().height()
      }, 300, function() {
        this.currentImageIndex -= 1;
      }.bind(this));
      
      this.container.animate({
        left: (this.container.position().left + this.photoWidth) + 'px', 
        height: this.prevImage().height()
      }, 500, function() {
        this.resetNav();
      }.bind(this));
    };
  },
  
  resetNav: function(){
    if (this.beginning()) {
      this.enableAction(this.nextLink);
      this.disableAction(this.prevLink);
    } else if (this.end()) {
      this.enableAction(this.prevLink);
      this.disableAction(this.nextLink);
    } else {
      this.enableAction(this.prevLink);
      this.enableAction(this.nextLink);
    };
  },
  
  end: function(){
    // return true if the container's right edge is in the same position as the wrapper's right edge.
    return this.container.position().left === -(this.container.width() - this.photoWidth);
  },
  
  beginning: function(){
    // return true if the container's left edge is in the same position as the wrapper's left edge.
    return this.wrapper.position().left === this.container.position().left;
  },
  
  disableAction: function(link){
    link.addClass('disabled');
  },
  
  enableAction: function(link) {
    link.removeClass('disabled');
  }
});

var Products = {
  initialize: function(products){
    this.elem = products ? $(products) : $("#products ul.product:not('#new_product')");
    this.selectedItem = null;

    var items = [];
    $.each(this.elem, function(i, elem) {
      var prod = new Product(elem);
      items.push(prod);
      if (prod.selected()) this.selectedItem = prod;
    });
    this.items = items;
  }
};

var Product = new Class({
  initialize: function(item){
    this.elem = $(item);
    this.header = $('li.head', this.elem);
    $("li.head:hover", this.elem).css("cursor", "pointer");
    this.body = $('li.body', this.elem).show().hide();
    this._selected = this.elem.hasClass('selected') || this.body.css('display') == 'block';

    this.header.click(this.toggle.bind(this));
    $('h2 a', this.header).click(this.toggle.bind(this));

    if (this.selected()) { this.select(); };
    
    $('a.edit_product', this.elem).click(function(e) {
      e.preventDefault();
      $.ajax({
        url: $(this).attr('href'), 
        dataType: 'script'
      });
    });
    
    this.elem.data("product", this);
    this.photoCollection = new ProductPhotoCollection(this);
  },
  
  selected: function(){
    return this._selected;
  },
  
  deselect: function(){
    $(document).trigger('product.deselect');
    this.body
      .animate({height: "hide", opacity: 0}, {duration: 500, queue: false})
      .animate({opacity: 1}, {duration: 500});
    this.elem.removeClass('selected');
    this._selected = false;
  },
  
  select: function(){
    $(document).trigger('product.select');
    if (Products.selectedItem) Products.selectedItem.deselect();
    this.photoCollection.reset();
    this.body.css({opacity: 0})
      .animate({opacity: 1, height: 'show'}, {duration: 500, queue: false});
    this.elem.addClass('selected');
    this._selected = true;
    Products.selectedItem = this;
  },
  
  toggle: function(e){
    e.currentTarget.blur();
    this.selected() ? this.deselect() : this.select();
    e.preventDefault();
    e.stopPropagation();
    return false;
  }
});

var ProductForm = new Class({
  initialize: function(elem){
    if (!$('body').hasClass('products-new')) {
      var that = this;
      this.elem = elem ? $(elem) : $('#new_product').hide();
      $(document).bind("newProduct.toggle", this.clicked.bind(this));

      $(".buttons", this.elem).append(this.cancel_link());
  
      $(document).bind("product.select", function() {
        if (this.visible()) $(document).trigger('newProduct.toggle');
      }.bind(this));
      
      if (!elem) {
        $('#add_product').click(this.clicked.bind(this));
      };
      
      $('.photo .delete_product_photo', this.elem).click(function(e) {
        e.preventDefault();
        var delete_link = $(this).parent();
        var undelete_link = $('<li>Marked for deletion. <a href="#">Undelete</a></li>');
        var admin_actions = delete_link.parents('.admin.actions');
        var img = admin_actions.siblings('img');
        var orig_img_src = img.attr('src');
        var thumb_img_src = orig_img_src.replace(/\/medium\//, '/thumb/');
        var delete_input = delete_link.children('.delete_photo');
        var photo_ids_field = delete_link.children('input.photo_ids');
        
        img
          .attr('src', thumb_img_src)
          .css({'float': 'left', marginRight: '10px', opacity: 0.5})
          .parent('.photo')
            .css({overflow: 'hidden'});
        
        photo_ids_field.val(null);

        $('a', undelete_link).click(function(e) {
          e.preventDefault();
          $(this).parent().remove();
          img.attr('src', orig_img_src).css({opacity: 1});
          admin_actions.css({
            position: 'absolute'
          });
          delete_link.show();
          delete_input.val(0);
          delete_link.parents('.photo').removeClass('deleted');
          photo_ids_field.val(admin_actions.parents('.photo').attr('id').match(/\d+$/)[0]);
        });
        
        admin_actions.css({
          position: 'relative', 
          overflow: 'hidden',
          display: 'block'
        })
        .append(undelete_link)
        .children('li')
          .css({
            display: 'inline', 
            width: '100%',
            color: '#933'
          }).children('a').css('display', 'inline-block');
        delete_link.hide();
        
        delete_link.parents('.photo').addClass('deleted');
        
        delete_input.val(1);
      });

      $('.photo .delete_new_product_photo', this.elem).live('click', function(e) {
        e.preventDefault();
        $(this).parents('.photo').animate({height: 0}, 200, function() { $(this).remove(); });
      });
      
      this.photoForm = $('.photo.new:first', this.elem).remove().clone(true);
      this.photoTemplate = $('.photo.template:first', this.elem).remove().removeClass('template').clone(true);
      this.newPhotoCount = 1;
      
      $('.add_photo_link', this.elem).click(this.addPhoto.bind(this));
      
      if ($('body').hasClass("admin")) {
        this.sortablePhotos = new Sortable({
          element: ".photos",
          context: this.elem, 
          items: ".photo", 
          sortableOptions: {
            update: this.resortPhotos
          }
        });
      };
      
      
      $('input[type="submit"]', this.elem).click(function(e) {
        this.resortPhotos();
      }.bind(this));
    }
  },
  
  resortPhotos: function(e, ui){
    var photos = $('.photo:not(".deleted")', $(this));
    var photo_i = 0;
    $.each(photos, function(i, photo) {
      if ($('img', photo).length > 0 || $('input[type="file"]', photo).val() !== '') {
        $('input.position', photo).val(photo_i + 1);
        photo_i += 1;
      };
    });
  },
  
  addPhoto: function(e){
    var self = this;
    this.newPhotoCount += 1;
    
    var form = $(this.photoForm.clone(true));
    $('input', form).each(function(i) {
      var e = $(this);
      e.attr('name', e.attr('name').replace(/\[photos_attributes\]\[\d+\]\[/, "[photos_attributes][NEW_" + self.newPhotoCount +  "]["));
      e.attr('id', e.attr('id').replace(/photos_attributes_\d+/, "photos_attributes_NEW_" + self.newPhotoCount));
    });
    
    $('.photos', this.elem).append(form);
    
    var input = $('input[type="file"]', form);
    new AjaxUpload(input, {
      action: "/photos",
      onSubmit: function(file, ext){
        input.attr('disabled', true);
      },
      onComplete: function(file, response){
        var json = JSON.parse(response).photo;
        var photo = self.photoTemplate.clone(true);
        $('input:not(".photo_ids")', photo).each(function(i) {
          var e = $(this);
          e.attr('name', e.attr('name').replace(/\[photos_attributes\]\[\d+\]\[/, "[photos_attributes][NEW_" + self.newPhotoCount +  "]["));
          e.attr('id', e.attr('id').replace(/photos_attributes_\d+/, "photos_attributes_NEW_" + self.newPhotoCount));
        });
        
        $('input.photo_ids', photo).val(json.id);
        
        $('img', photo).each(function(i) {
          var e = $(this);
          e.attr('src', '/system/images/' + json.id + '/medium/' + json.image_file_name);
        });

        form.replaceWith(photo);
        photo.before('<input id="product_photos_attributes_' + self.newPhotoCount + '_id" name="product[photos_attributes][' + self.newPhotoCount + '][id]" type="hidden" value="' + json.id + '" />');
      }
    });
    e.preventDefault();
  },
  
  cancel_link: function(){
    return $('<a href="#cancel" class="cancel">Cancel</a>').click(function(e) {
     this.clicked(e);
     this.reset();
    }.bind(this));
  },
  
  visible: function(){ return this.elem.css('display') == 'block'; },
  
  clicked: function(e){
    e.preventDefault();
    if (Products.selectedItem) Products.selectedItem.deselect();
    this.elem.animate({height: 'toggle'}, {duration: 500});
  },
  
  reset: function(){
    $('input[type=text], input[type=file], textarea', this.elem).val("");
    $('select', this.elem).val(1);
    $('input[type=checkbox]', this.elem).attr('checked', false);
  },
  
  hide: function(){
    this.elem.hide();
  }
});

var SubCategoryDisplay = (function() {
  function Thumb (element, container) {
    var element = $(element);
    var _selected = element.hasClass('selected');
    var image = function() {
      var parts = $('img', element).attr('src').split(/\//);
      return {
        filename: parts[parts.length-1].split(/\?/)[0],
        id: parts[3]
      };
    }();
    var title = $('h5', element);
    var href = $('a', element).attr('href');

    element.click(select);
    
    function selected () { return _selected; };
        
    function select (e) {
      if (e) { e.preventDefault(); };
      if (!_selected) {
        container.thumbs.invoke('deselect');
        container.display.changeTo(self);
        _selected = true;
        element.addClass('selected');
      };
    };
    
    function deselect () {
      _selected = false;
      element.removeClass('selected');
    };
    
    function toggle (e) {
      if (e) { e.preventDefault(); };
      _selected ? deselect() : select();
    };
    
    var self = {
      element: element,
      toggle: toggle,
      select: select,
      deselect: deselect,
      image: image,
      title: title,
      href: href
    };
    
    return self;
  };
  
  function ThumbCollection (display) {
    var container = function() {
      var element = $('.thumbs', display.container);
      var rightSide = parseInt(element.offset().left + (position().width / 2) + 200);
      var leftSide = parseInt(element.offset().left + (position().width / 2) - 200);
      
      function position () {
        var left = element.position().left;
        var right = left + element.width();
        var width = element.width();
        var height = element.height();
        
        return {
          left: left,
          right: right,
          width: width,
          height: height
        };
      };
      
      return {
        element: element,
        position: position,
        offset: element.offset,
        rightSide: rightSide,
        leftSide: leftSide
      };
    }();
    
    var thumbs_container = function() {
      var element = $('ul', container.element).css({height: container.element.height(), position: 'relative', left: 0});
      var self = this;
      
      function position () {
        var left   = this.left   = parseInt(element.css('left')),
            right  = this.right  = left + element.width(),
            width  = this.width  = element.width(),
            height = this.height = element.height();
        
        return {
          left: left,
          right: right,
          width: width,
          height: height
        };
      }
      
      function move (e) {
        var distance = 0, current_position = e.pageX;
        if (!end()) {
          if (current_position > container.rightSide - 100 && current_position < container.rightSide) {
            distance = 1;
          } else if (current_position > container.rightSide) {
            distance = 5;
          };
        };
        
        if (!beginning()) {
          if (current_position < container.leftSide + 100 && current_position > container.leftSide) {
            distance = -1;
          } else if (current_position < container.leftSide) {
            distance = -5;
          };
        };
        
        element.css({ left: position().left - distance });
      }
      
      function startAnimation (e) {
        if (self.interval !== undefined) { clearInterval(self.interval); };
        self.interval = setInterval(move, 2, e);
        
        container.element.bind('mousemove', startAnimation);
      }
      
      function stopAnimation (e) {
        clearInterval(self.interval);
        container.element.unbind('mousemove');
      }
      
      return {
        element: element,
        position: position,
        move: move,
        startAnimation: startAnimation,
        stopAnimation: stopAnimation
      };
    }();
    
    function end () {
      return thumbs_container.position().right <= container.position().right;
    }
    
    function beginning () {
      return thumbs_container.position().left >= 0;
    }
    
    function each (callback) {
      $.each(thumbs, callback);
    };
    
    function invoke (method) {
      $.each(thumbs, function(i, thumb) {
        thumb[method]();
      });
    };

    var thumbs = [], thumb_elems = $('li', container.element);
    thumb_elems.each(function(i, thumb) {
      var thumb = new Thumb(thumb, display);
      thumbs.push(thumb);
      if (i >= thumb_elems.length - 5 && thumb_elems.length > 5) {
        thumb.title.css({left: 'auto', right: 0, 'text-align': 'right'});
      };
      
      if (i + 1 == thumb_elems.length) {
        thumb.element.css('margin-right', 0);
      };
    });

    container.element.hover(thumbs_container.startAnimation, thumbs_container.stopAnimation);

    thumbs_container.element.css('opacity', 0).queue(function() {
      $('img', $(this)).load(function() {
        var new_width = function() {
          var thumb0 = thumbs[0].element,
              thumb1 = thumbs[1].element,
              margin = parseInt(thumb0.css('margin-right')),
              width  = parseInt(thumb1.outerWidth()),
              width2 = parseInt(thumb0.outerWidth());

          return ((thumbs.length - 1) * (width + margin)) + width2;
        }();
      
        thumbs_container.element.width(new_width);
      });
      thumbs_container.element.animate({'opacity': 1}, 200).show();
      $(this).dequeue();
    }).queue(function() {
      $(this).show();
      $(this).dequeue();
    });
      
    return {
      thumbs: thumbs,
      each: each, 
      invoke: invoke
    };
  };
  
  function Display (display) {
    var element      = $('.display', display.container),
        description  = $('.description', element),
        title        = $('h5', description),
        product_link = $('a', description);
    
    function changeTo (thumb) {
      var currentScrollTop = $(document).scrollTop();
      var img = $('img', element);
      var newImg = function() {
        var parts = img.attr('src').split(/\//);
        parts[3] = thumb.image.id;
        parts[parts.length - 1] = thumb.image.filename;
        return $("<img />").attr('src', parts.join("/")).hide();
      }().insertAfter(img);

      newImg.load(function() {
        img.fadeOut('show').remove();
        newImg.fadeIn('show');
        $(document).scrollTop(currentScrollTop);
        title.text(thumb.title.text());
        product_link.attr('href', thumb.href);
      });
    }
    
    return {
      changeTo: changeTo
    };
  };
    
  function initialize (element) {
    this.container = $(element);
    this.thumbs = new ThumbCollection(this);
    this.display = new Display(this);
  };
    
  return {
    initialize: initialize
  };
})();

$(document).ready(function() {
  Products.initialize();
  if ($('.sub_categories').length) {
    SubCategoryDisplay.initialize('.sub_categories');
  };
  
  if ($('body').hasClass('admin')) {
    new ProductForm;
  };
});
