window.addEvent('domready', function() {
  // This is for the checkboxes that select all checkboxes in the form.
  $$('table input.toggle').each(function(toggle_item) {
    toggle_item.addEvent('click', function() {
      toggle_item.getParent('table').getElements('input[type="checkbox"]').set('checked', toggle_item.get('checked'));
    });
  });
  // Initialise the slideshow whenever it is found.
  $$('.slideshow').each(function(slideshow_item) {
    new Slideshow({
      container : slideshow_item
    });
  });

  if($('ProductSidebarForm')) {
    $('ProductSidebarForm').addEvent('submit', function(event) {
      if(event) event.stop();
      var form = $('ProductSidebarForm');
      $('product_listing').empty();
      $('product_listing').getNext().empty();
      $url = ($('gourmetMarketBrandId') ? '/gourmet_market_items/search' : 'hampers/search');
      var request = new Request({
        'method' : 'get',
        'url' : $url,
        onSuccess : function(result) {
          var div = new Element('div', {
            html : result
          })
          div.getFirst('ul').replaces($('product_listing'));
          div.getLast('ul').replaces($('product_listing').getNext());
          $('product_listing').getNext().getChildren().each(function(item) {
            item.addEvents({
              'click' : function(event) {
                if(event) event.stop();
                window.scrollTo(0, 0);
                request.send(form.toQueryString().replace(/data\[(.*?)\]/g, '$1') + '&page=' + this.get('text'));
                $('product_listing').empty();
                $('product_listing').getNext().empty();
              },
              'keypress' : function(event) {
                event.stop();
                this.fireEvent('click');
              }
            });
          });
        }
      }).send(form.toQueryString().replace(/data\[(.*?)\]/g, '$1'));
      window.scrollTo(0, 0);
    });
    $('ProductSidebarForm').fireEvent('submit');
  }

  if($('FeaturedProductDiscountType')) {
    new Toggler({
      element : $('FeaturedProductDiscountType'),
      toggle_on : [$('FeaturedProductDiscountAppliedTo').getParent(), $('FeaturedProductDiscountValue')],
      toggle_off : [$('FeaturedProductDiscountValueGourmetMarketItem')],
      comparison : function(element) {
        return element.get('value') != 'item';
      }
    });
  }

  if($('VoucherDiscountType')) {
    new Toggler({
      element : $('VoucherDiscountType'),
      toggle_on : [$('VoucherDiscountAppliedTo').getParent(), $('VoucherDiscountValue')],
      toggle_off : [$('VoucherDiscountValueGourmetMarketItem')],
      comparison : function(element) {
        return element.get('value') != 'item';
      }
    });
  }

  $$('.OptionCategoryCheckbox').each(function(item) {
    new Toggler({
      element : item,
      comparison : function(element) {
        return element.get('checked');
      }
    });
  });

  if($('checkout_form')) {
    var header = $$('body > section > h2')[0].get('text');
    $$('body > section > h2').destroy();
    var hgroup = new Element('hgroup', {
      'class' : 'inline_headers'
    }).inject($$('body > section')[0], 'top');
    new Element('h2', {
      text : header
    }).inject(hgroup);
    var steps = new Element('h3', {
      id : 'checkout_steps'
    }).inject(hgroup);
    $('checkout_form').getElements('legend').each(function(legend_item,
      legend_index) {
      legend_index += 1;
      var span = new Element('span', {
        id : 'checkout_step_' + legend_index,
        text : legend_item.get('text').replace(/^Step\s[0-9]+\:\s(.*)$/i, '$1')
      }).inject(steps);
      new Element('span', {
        text : legend_index
      }).inject(new Element('a', {
        href : '#',
        events : {
          click : function(event) {
            if(event) event.preventDefault();
          }
        }
      }).store('page', legend_index).inject(span, 'top'));
      legend_item.set('text', '');
      legend_item.setStyle('padding', '0');
    });
    $('checkout_step_1').addClass('bold');
        
    new Checkout_Validation({
      container : $('checkout_form'),
      step : steps
    });

    new Checkout_Calculation();
  }
    
  if($('DynamicHomeFeatured') || $('HamperOptionCategories')) {
    var parent = null;
    var parent_class = null;
    if($('DynamicHomeFeatured')) {
      parent = $('DynamicHomeFeatured');
      parent_class = 'dynamics_featured';
    } else if($('HamperOptionCategories')) {
      parent = $('HamperOptionCategories');
      parent_class = 'categories_options';
    }
    if(parent && parent_class) {
      parent.setStyle('display', 'none');
      $$('.' + parent_class).each(function(featured_item) {
        featured_item.setStyle('display', 'block');
        var featured_selected = function(item) {
          if(item.hasClass(parent_class + '_end') && item.selectedIndex > 0) {
            item.removeClass(parent_class + '_end')
            var item_new = item.getParent().clone(true);
            item_new.getFirst('select').addEvents({
              'click' : function() {
                featured_selected(this);
              },
              'keyup' : function() {
                featured_selected(this);
              }
            });
            item_new.getFirst('select').selectedIndex = 0;
            item_new.getFirst('select').addClass(parent_class + '_end');
            item_new.inject(item.getParent(), 'after');
          }
          var home_featured = new Array();
          $$('.' + parent_class).each(function(featured_item, featured_index) {
            if(featured_item.selectedIndex > 0) {
              home_featured[featured_index] = featured_item.options[featured_item.selectedIndex].value;
            }
          });
          parent.set('text', home_featured.join(','));
        }
        featured_item.addEvents({
          'click' : function() {
            featured_selected(this);
          },
          'keyup' : function() {
            featured_selected(this);
          }
        });
      });
    }
  }

  // Greyout on submit buttons being clicked to show cart overlay.
  if(Browser.Engine.trident == false || Browser.Engine.version >= 5) {
    $$('.cart_form').each(function(form) {
      form.addEvents({
        'submit' : function(event) {
          if(event) event.preventDefault();
          var size = window.getSize();
          var greyout = new Element('div', {
            id : 'greyout'
          }).inject(document.body);
          new Request({
            url : form.get('action'),
            method : 'post',
            onSuccess : function(result) {
              new Element('div', {
                id : 'greyout_content',
                html : result,
                styles : {
                  top : Math.round((size.y / 100) * 10),
                  height : Math.round((size.y / 100) * 80)
                }
              }).inject(greyout);
              new Element('div', {
                id : 'greyout_close',
                styles : {
                  top : Math.round((size.y / 100) * 10) - 15,
                  left : Math.round((size.x - 998) / 2) - 15
                },
                events : {
                  click : function() {
                    greyout.destroy();
                  },
                  keyup : function() {
                    greyout.destroy();
                  }
                }
              }).inject(greyout);
            }
          }).send(form.toQueryString());
        }
      });
    });
  }
});

var Checkout_Validation = new Class({
  Implements : Options,
  options : {
    container : null,
    fieldsets : null,
    current : 1
  },
  initialize : function(options) {
    var initialize_class = this;
    this.setOptions(options);
    this.options.fieldsets = this.options.container.getElements('fieldset');
    for(var i = 0; i < this.options.fieldsets.length; i++) {
      if(i > 0) {
        var p = new Element('p', {
          'class' : 'center navigation submit'
        }).inject(this.options.fieldsets[i]);
        if(i > 1) {
          this.options.fieldsets[i].setStyle('display', 'none');
          new Element('input', {
            'type' : 'submit',
            'class' : '',
            value : 'Previous Step',
            events : {
              click : function(click_event) {
                click_event.preventDefault();
                initialize_class.previousstep();
              }
            }
          }).inject(p);
        }
        if(i < this.options.fieldsets.length - 1) {
          new Element('input', {
            'type' : 'submit',
            'class' : '',
            value : 'Next Step',
            events : {
              click : function(click_event) {
                click_event.preventDefault();
                initialize_class.nextstep();
              }
            }
          }).inject(p);
        }
      }
    }
    $$('.submit input[type="submit"]').addEvent('click', function(click_event) {
      if(!initialize_class.check_payment()) {
        click_event.preventDefault();
      }
    });
    $('checkout_step_1').addEvent('click', function(event) {
      if(event) event.preventDefault();
      initialize_class.navigate(1, false);
    });
    $('checkout_step_2').addEvent('click', function(event) {
      if(event) event.preventDefault();
      initialize_class.navigate(2, false);
    });
    $('checkout_step_3').addEvent('click', function(event) {
      if(event) event.preventDefault();
      initialize_class.navigate(3, false);
    });
    $('checkout_step_4').addEvent('click', function(event) {
      if(event) event.preventDefault();
      initialize_class.navigate(4, false);
    });
  },
  previousstep : function() {
    this.navigate(this.options.current - 1, true);
  },
  nextstep : function() {
    this.navigate(this.options.current + 1);
  },
  navigate : function(index, nocheck) {
    if(index > 0 && index < this.options.fieldsets.length && (nocheck || this.check(this.options.fieldsets[this.options.current]))) {
      this.options.fieldsets[this.options.current].setStyle('display', 'none');
      this.options.current = index;
      this.options.fieldsets[this.options.current].setStyle('display', 'block');
      window.scrollTo(0, 0);
      $$('.inline_headers span').removeClass('bold');
      $('checkout_step_' + index).addClass('bold');
    }
  },
  check : function(fieldset) {
    var success = true;
    fieldset.getElements('.error').removeClass('error');
    fieldset.getElements('.input.select select').each(function(select_item) {
      if(select_item.selectedIndex == 0 && select_item.get('id') != 'payment_term') {
        select_item.addClass('error');
        success = false;
      }
    });
    fieldset.getElements('.required ~ input').each(function(input_item) {
      switch(input_item.get('type')) {
        case 'text':
          if(input_item.get('value').length == 0) {
            input_item.addClass('error');
            success = false;
          }
          break;
      }
    });
    switch(fieldset.get('id')) {
      case 'checkout_items':
        success &= this.checkout_items();
        break;
      case 'checkout_contact':
        success &= this.check_contact();
        break;
      case 'checkout_delivery':
        success &= this.check_delivery();
        break;
      case 'checkout_payment':
        success &= this.check_payment();
        break;
      default:
        success = false;
        break;
    }
    if(!success) {
      alert('You\'ve made a mistake in one of the fields. Please check the highlighted fields for problems and rectify them appropriately.')
    }
    return success;
  },
  checkout_items : function() {
    var success = true;
    $$('.hamper_message', '.hamper_message_greeting', '.hamper_message_signature').each(function(message_item) {
      var message = message_item.get('value').replace(/\W+/g, ' ');
      var message_words = message.split(' ');
      if(message_words.length > 30) {
        message_item.addClass('error');
        success = false;
      }
    });
    return success;
  },
  check_contact : function() {
    var success = true;
    if($('email').get('value')
      .test(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/)) {
      $('email').addClass('error');
      success = false;
    }
    return success;
  },
  check_delivery : function() {
    var success = true;
    if(!$('recipient_postcode').get('value').test(/^[0-9]{4}$/)) {
      $('recipient_postcode').addClass('error');
      success = false;
    }
    // @todo We're having problems with this, needs to be fixed at a later date.
    //        var date_now = Date.now();
    //        var date_post = new Date($('ddateYear').options[$('ddateYear')
    //            .selectedIndex].value, $('ddateMonth').selectedIndex, $('ddateDay')
    //            .selectedIndex + 1);
    //        date_post = date_post.setHours(10);
    //        if(date_now > date_post) {
    //            $('ddateMonth').addClass('error');
    //            $('ddateDay').addClass('error');
    //            $('ddateYear').addClass('error');
    //            success = false;
    //        }
    if(!$('conditions').checked) {
      $('conditions').addClass('error');
      success = false;
    }
    return success;
  },
  check_payment : function() {
    var success = true;
    if($('PaymentTypeLayBy') && $('PaymentTypeLayBy').checked) {
      if($('payment_term').selectedIndex == 0) {
        $('payment_term').addClass('error');
        success = false;
      }
    }
    return success;
  }
});

var Checkout_Calculation = new Class({
  voucher : null,
  voucher_request : null,
  items : null,
  delivery_hampers : 0,
  delivery_gourmet_market_items : 0,
  initialize : function() {
    this.elements = {
      voucher_field : $('voucher'),
      voucher_status : $('voucher_status'),
      layby_container : $('layby'),
      layby_switch : $('PaymentTypeLayBy'),
      layby_period_select : $('payment_term'),
      layby_period : $('layby_period'),
      layby_installment : $('layby_installment'),
      layby_total : $('layby_total'),
      full_switch : $('PaymentTypeFullPay'),
      delivery_field_hampers : $('delivery_type_hampers'),
      delivery_field_gourmet_market_items : $('delivery_type_gourmet_market_items'),
      delivery_summary_hampers : $('summary_delivery_type_hampers'),
      delivery_summary_gourmet_market_items : $('summary_delivery_type_gourmet_market_items'),
      delivery_summary_total : $('summary_delivery_total'),
      discount_summary : $('summary_discount'),
      total_summary : $('summary_total')
    }
    var this_class = this;
    // Set events on delivery charge select boxes to trigger recalculation.
    this.items = JSON.decode($('checkout_json').get('value'));
    if(this.elements.voucher_field && this.elements.voucher_status) {
      // Add event to voucher field to retrieve event on keyup events.
      this.elements.voucher_field.addEvent('keyup', function() {
        this_class.voucher_retrieve();
      });
      // Populate voucher status with default label.
      this.voucher_retrieve();
    }
    if(this.elements.delivery_field_hampers) {
      this.elements.delivery_field_hampers.addEvents({
        'click' : function() {
          this_class.delivery_change_hampers();
        },
        'keyup' : function() {
          this_class.delivery_change_hampers();
        }
      });
    }
    this.delivery_change_hampers();
    if(this.elements.delivery_field_gourmet_market_items) {
      this.elements.delivery_field_gourmet_market_items.addEvents({
        'click' : function() {
          this_class.delivery_change_gourmet_market_items();
        },
        'keyup' : function() {
          this_class.delivery_change_gourmet_market_items();
        }
      });
    }
    this.delivery_change_gourmet_market_items();
    $$('#PaymentTypeLayBy', '#PaymentTypeFullPay').addEvents({
      'click': function() {
        this_class.payment_change();
      },
      'keyup' : function() {
        this_class.payment_change();
      }
    });
    this.payment_change();
    if(this.elements.layby_period_select) {
      this.elements.layby_period_select.addEvents({
        'click': function() {
          this_class.recalculate();
        },
        'keyup' : function() {
          this_class.recalculate();
        }
      });
    }
  },
  recalculate : function() {
    var total = 0;
    var delivery = 0;
    var discount = 0;
    if(this.items.hampers) {
      this.items.hampers.each(function(item) {
        total += parseFloat(item['price']) * item['quantity'];
        delivery += parseFloat(item['delivery']) * item['quantity'];
        discount += parseFloat(item['discount']);
      });
    }
    if(this.items.gourmet_market_items) {
      delivery += parseFloat(this.items.gourmet_market_items[0]['delivery']);
      this.items.gourmet_market_items.each(function(item) {
        total += parseFloat(item['price']) * item['quantity'];
        discount += parseFloat(item['discount']);
      });
    }
    total += delivery - discount;
    $('summary_delivery_total').set('html', delivery.toFixed(2));
    $('summary_discount').set('html', discount.toFixed(2));
    $('summary_total').set('html', total.toFixed(2));
    if(this.elements.layby_period_select) {
      var layby_period = this.elements.layby_period_select.options[this.elements.layby_period_select.selectedIndex].value;
      switch(layby_period) {
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
          this.elements.layby_period.set('html', layby_period);
          var installment = (total.toFixed(2) / layby_period).toFixed(2);
          this.elements.layby_installment.set('html', installment);
          this.elements.layby_total.set('html', installment);
          break;
        default:
          this.elements.layby_period.set('html', 1);
          this.elements.layby_installment.set('html', total.toFixed(2));
          this.elements.layby_total.set('html', total.toFixed(2));
          break;
      }
    }
  },
  payment_change : function() {
    if(this.elements.layby_switch) {
      if(this.elements.layby_switch.checked) {
        this.elements.layby_container.setStyle('display', 'block');
      } else {
        this.elements.layby_container.setStyle('display', 'none');
      }
    }
  },
  delivery_change_hampers : function() {
    if(this.elements.delivery_field_hampers) {
      var delivery = this.delivery_hampers = parseFloat(this.elements.delivery_field_hampers.options[this.elements.delivery_field_hampers.selectedIndex].value);
      var this_class = this;
      if(this.items.hampers) {
        this.items.hampers.each(function(item) {
          item.delivery = delivery;
          this_class.item_subtotal_calculate(item, this_class.voucher);
        });
      }
      this.elements.delivery_summary_hampers.set('html', this.elements.delivery_field_hampers.options[this.elements.delivery_field_hampers.selectedIndex].innerHTML);
      this.recalculate();
    } else {
      this.elements.delivery_summary_hampers.set('html', 'No Hampers');
    }
  },
  delivery_change_gourmet_market_items : function() {
    if(this.elements.delivery_field_gourmet_market_items) {
      var delivery = this.delivery_gourmet_market_items = parseFloat(this.elements.delivery_field_gourmet_market_items.options[this.elements.delivery_field_gourmet_market_items.selectedIndex].value);
      var this_class = this;
      if(this.items.gourmet_market_items) {
        this.items.gourmet_market_items.each(function(item) {
          item.delivery = delivery;
          this_class.item_subtotal_calculate(item, this_class.voucher);
        });
      }
      this.elements.delivery_summary_gourmet_market_items.set('html', this.elements.delivery_field_gourmet_market_items.options[this.elements.delivery_field_gourmet_market_items.selectedIndex].innerHTML);
      this.recalculate();
    } else {
      this.elements.delivery_summary_gourmet_market_items.set('html', 'No Gourmet Market Item Products');
    }
  },
  item_subtotal_calculate : function(item, voucher) {
    if(item && voucher) {
      var subject = parseFloat(item.price);
      if(voucher.delivery == 1) subject = parseFloat(item.delivery);
      if(voucher.unit == '%') {
        item.discount = (subject / 100) * voucher.reduction;
      } else {
        item.discount = Math.max(subject, voucher.reduction);
      }
      item.subtotal = parseFloat(item.price) + parseFloat(item.delivery) - parseFloat(item.discount);
    } else {
      item.discount = 0;
      item.subtotal = parseFloat(item.price) + parseFloat(item.delivery);
    }
  },
  voucher_retrieve : function() {
    if(this.voucher_request) $clear(this.voucher_request);
    this.elements.voucher_status.setStyle('display', 'block');
    if(this.elements.voucher_field.get('value') != '') {
      this.elements.voucher_status.set('html', 'Checking Voucher Code...').removeClass('flashError').addClass('flashMessage');
      var this_class = this;
      var request = new Request.JSON({
        'url' : '/vouchers/retrieve/' + this_class.elements.voucher_field.get('value'),
        'method' : 'get',
        onSuccess : function(json) {
          if(json) {
            this_class.voucher = json['Voucher'];
            this_class.elements.voucher_status.set('html', 'Valid Voucher Code: ' + json['Voucher']['title']);
            this_class.delivery_change_gourmet_market_items();
            this_class.delivery_change_hampers();
          } else {
            this.onFailure();
          }
        },
        onFailure : function() {
          this_class.voucher = null;
          this_class.elements.voucher_status.set('html', 'Not A Valid Voucher Code!').removeClass('flashMessage').addClass('flashError');
          this_class.delivery_change_gourmet_market_items();
          this_class.delivery_change_hampers();
        }
      });
      this.voucher_request = function() {
        request.send()
      }.delay(500);
    } else {
      this.voucher = null;
      this.elements.voucher_status.removeClass('flashError').addClass('flashMessage').set('text', 'Enter a voucher code if you have one, and look here to see your discount.');
      this.delivery_change_gourmet_market_items();
      this.delivery_change_hampers();
    }
  }
});

var Slideshow = new Class({
  Implements : Options,
  options : {
    period : 5000,
    container : null,
    selectors : new Array(),
    images : new Array(),
    last : 0
  },
  initialize : function(options) {
    var this_class = this;
    this.setOptions(options);
    if(this.options.container) {
      this.options.selectors = this.options.container.getElements('nav li');
      this.options.images = this.options.container.getChildren('a.image');
      this.options.images.fade('hide');
      this.options.images[0].fade('in');
      var periodical = this.animate.periodical(this.options.period, this);
      for(var i = 0; i < this.options.selectors.length; i++) {
        this.options.selectors[i].store('key', i);
        this.options.selectors[i].addEvent('click', function(click_event) {
          click_event.preventDefault();
          $clear(periodical);
          this_class.set(this_class.options.last, this.retrieve('key'));
          this_class.options.last = this.retrieve('key');
          periodical = this_class.animate.periodical(this_class.options.period, this_class);
        });
      }
    }
  },
  animate : function() {
    var position = this.options.last + 1;
    if(position >= this.options.images.length) position = 0;
    this.set(this.options.last, position);
    this.options.last = position;
  },
  set : function(previous, current) {
    this.options.images[previous].fade('out');
    this.options.images[previous].removeClass('current');
    if(this.options.selectors[previous]) {
      this.options.selectors[previous].removeClass('selected');
    }
    this.options.images[current].fade('in');
    this.options.images[current].addClass('current');
    if(this.options.selectors[current]) {
      this.options.selectors[current].addClass('selected');
    }
  }
});

var Toggler = new Class({
  Implements : Options,
  options : {
    element : null,
    toggle_on : null,
    toggle_off : null,
    comparison : function() {}
  },
  toggle : null,
  initialize : function(options) {
    this.setOptions(options);
    this.toggle = this.options.element.getNext('.toggle');
    if(!this.toggle) this.toggle = this.options.element.getParent().getNext('.toggle');
    this.options.element.addEvents({
      click : function() {
        if(this.options.comparison.run(this.options.element, this)) {
          if(this.toggle) this.toggle.setStyle('display', 'block');
          if(this.options.toggle_on) this.options.toggle_on.each(function(item) {
            item.setStyle('display', 'block');
          });
          if(this.options.toggle_off) this.options.toggle_off.each(function(item) {
            item.setStyle('display', 'none');
          });
        } else {
          if(this.toggle) this.toggle.setStyle('display', 'none');
          if(this.options.toggle_on) this.options.toggle_on.each(function(item) {
            item.setStyle('display', 'none');
          });
          if(this.options.toggle_off) this.options.toggle_off.each(function(item) {
            item.setStyle('display', 'block');
          });
        }
      }.bindWithEvent(this),
      keyup : function() {
        this.fireEvent('click');
      }
    });
    this.options.element.fireEvent('click');
  }
});