jQuery(function() {
  (function slide() {
    $('#druckmaschine').show();
    
    $('#attached_assets').cycle({
      timeout: 3000,
      speed: 3000,
      delay: 0
    });
  })();
  
  // IE Fixes
  $('#thumb_switcher #zooms img').hide();
  
  app.optionChooser('#options', 'table.machines tbody tr');
  app.thumbSwitcher('#thumb_switcher', '#thumbs', '#zooms');
  
  var requiredMessage = function() {
    return $('#required_message').text();
  }
  
  $('form#mailer').validate({
    messages: {
      "mailer[company]": requiredMessage(),
      "mailer[name]": requiredMessage(),
      "mailer[telephone]": requiredMessage(),
      "mailer[email]": requiredMessage()
    }
  });
  
  // Expects 'href' attribute of each 'a' to point to large version of image
  $('a.lightbox').lightBox({
    imageLoading: '/images/lightbox/ico-loading.gif',
    imageBtnClose: '/images/lightbox/btn-close.gif',
    imageBtnPrev: '/images/lightbox/btn-prev.gif',
    imageBtnNext: '/images/lightbox/btn-next.gif'
  });
  
});

var app = {};
  
/**
 * Limit list of items by choosing from options
 * 
 * @param chooser
 *        The chooser element provides the UI to choose from available options
 * @param items
 *        Choose from those items
 * @parm  option_prefix
 *        Prefix of options without the trailing underscore (_), 
 *        e.g. 'type' for options 'type_fresh', 'type_rotten' etc.
 */
app.optionChooser = function(chooser, items, option_prefix) {
  var that = this;
  this.chooser = $(chooser);
  this.items = $(items);
  this.buttons = $(chooser).children('li');
  this.button_all = $(chooser).children('li.opt_all')
  
  var initialize = function() {
    that.chooser.click(function(event) {
      var target = $(event.target)
      if(target.is('li[class^=opt_]')) {
        var opt = option(event.target);
        opt.toggle();
      }
    });
  };
  
  var listIsEmpty = function() {
    return (that.items.filter(':visible').length < 1)
  };
  
  /**
   * Return option that can be toggled
   *
   * @param element
   *        Element (or selector of element) with option as class
   */
  var option = function(element) {
    var element = $(element);
    
    var getOptionIdFromClass = function(element) {
      return element[0].className.match(/opt_(\w+)/)[1];
    };
    
    var getClassFromOptionId = function(option_id) {
      return 'opt_' + option_id;
    };
    
    var disableAll = function() {
      
    };
    
    var enableAll = function() {
      
    };
    
    return({
      element: element,
      id: function() {
        return getOptionIdFromClass(element);
      },
      klassName: function() {
        return getClassFromOptionId(this.id());
      },
      isAll: function() {
        return this.id() === 'all';
      },
      items: function() {
        var parent = this;
        return({
          hide: function() {
            if(parent.isAll()) {
              that.items.hide();
            } else {
              that.items.filter('.' + parent.klassName()).hide();
            }
          },
          show: function() {
            if(parent.isAll()) {
              that.items.show();
            } else {
              if(that.button_all.hasClass('checked')) {
                that.items.hide();
              }
              that.items.filter('.' + parent.klassName()).show();
            }
          }
        })
      },
      toggle: function() {
        // Uncheck
        if(this.element.hasClass('checked')) {
          this.items().hide();
          
          if(this.isAll()) {
            that.buttons.removeClass('halfchecked');
            that.button_all.removeClass('checked');
          }
          this.element.removeClass('checked');
        
        // Check
        } else {
          this.items().show();
          
          if(this.isAll()) {
            that.buttons.removeClass('checked')
            that.buttons.filter(':not(.opt_all)').addClass('halfchecked');
          } else {
            that.button_all.removeClass('checked');
            that.buttons.removeClass('halfchecked');
          }
          this.element.addClass('checked');
        }
        
        // Show or hide message
        if(listIsEmpty()) {
          $('#no_machines_with_given_options').show();
          $('table.machines').hide();
        } else {
          $('#no_machines_with_given_options').hide();
          $('table.machines').show();
        }
      },
    });
  }
  
  initialize();
  return this;
}

/**
 * Display clicked thumb in large size.
 *
 * Note: It is expected, that thumbs and zooms have the same number of images.
 *       Association of zoom image to thumb image is based on index.
 * 
 * @param switcher
 *        The switcher element is parent of thumbs and zooms
 * @param thumbs
 *        Parent element of thumb images. Expects selector.
 * @param zooms
 *        Parent element of zoom images. Expects selector.
 */
app.thumbSwitcher = function(switcher, thumbs, zooms) {
  var that = this;
  this.switcher = $(switcher);
  this.thumbs = this.switcher.find(thumbs).find('img');
  this.zooms = this.switcher.find(zooms).find('img');
  this.activeSet = undefined;
  this.imageSets = undefined;
  
  var initialize = function() {
    that.activeSet = buildImageSet(0);
    that.activeSet.activate();  // Could be hidden because of IE fix in action
    that.imageSets = that.thumbs.map(buildImageSet);
    
    that.thumbs.click(function() {
      var clicked_thumb = this;
      var index_of_thumb = undefined;
      that.thumbs.each(function(index) {
        if(this === clicked_thumb) {
          index_of_thumb = index;
        }
      });
      that.imageSets[index_of_thumb].activate();
    });
  };
  
  // Build set of thumb and zoom based on index
  // (i.e. show zoom image of set)
  var buildImageSet = function(index) {
    return {
      thumb: $(that.thumbs[index]),
      zoom: $(that.zooms[index]),
      activate: function() {
        that.activeSet.deactivate();
        that.activeSet = this;
        this.zoom.show();
        this.thumb.addClass('active');
      },
      deactivate: function() {
        this.zoom.hide();
        this.thumb.removeClass('active');
      }
    }
  }
  
  initialize();
  return this;
};
