/*
Please do not edit this file without contacting me, as your changes might get
lost.

The file has grown more complex than expected, so I'm considering whether to
refactor to an observer/observable model.
*/

// attachBuyBehavior assumes that 'this' refers to the '.pp-buy form' element
var attachBuyBehavior = function () {
  if (this.down('.pp-variation')) {
    BuyBehaviorSelect.attach(this);
  } else {
    BuyBehaviorSingle.attach(this);
  }
}


// Abstract base class:
// - Enables or disables the add to cart button.
// - Disallow clicks on the add to cart button if the product is not available.
var BuyBehaviorBase = Behavior.create({

  AVAILABILITY_STATUS_CODES: $A([1, 2, 3]),

  initialize: function () {
    this.update();
  },


  elements_add_to_cart_button: function () {
    return this.element.select('.pp-add-to-cart-button');
  },

  elements_sold_out_button: function () {
    return this.element.select('.pp-sold-out-button');
  },

  elements_availability_notification: function (s) {
    if (s) return this.element.select('.pp-availability-'+s);
  },


  add_to_cart_error_msg: function () {

    // check availability
    var s = this.current_availability();
    if (s == 1)
      return 'Dieses Produkt ist vorübergehend ausverkauft. Wir erwarten eine neue Lieferung in 1 bis 4 Wochen.';
    if (s < 1)
      return 'Dieses Produkt ist derzeit nicht lieferbar.';

    // ok, allow add to cart
  },


  update_add_to_cart_button: function (s) {
    if (s > 1 || !s) {
      // available or unknown
      this.elements_sold_out_button().invoke('hide');
      this.elements_add_to_cart_button().invoke('show');
    } else {
      // sold out
      this.elements_add_to_cart_button().invoke('hide');
      this.elements_sold_out_button().invoke('show');
    }
  },

  update_availability_mail: function (s) {
    var elem = this.element.down('.availability-notification');
    if (!elem) return;
    if (s > 1 || !s) {
      // available or unknown
      if (elem.visible()) elem.blindUp();
    } else {
      // sold out
      if (!elem.visible()) elem.blindDown();
    }
  },

  // smx_sm: added for basic non-variant articles' availability
  update_availability: function (s) {
    if (s) {
      // available
      this.elements_availability_notification(s).invoke('show');
    }
  },
  // smx_sm: end

  update: function () {
    var tst = this.current_availability();
    this.update_add_to_cart_button(this.current_availability());
    // smx_sm: added for non-variant articles' availability
    this.update_availability(this.current_availability());
    // smx_sm: end
    this.update_availability_mail(this.current_availability());
  },


  add_to_cart_button_clicked: function (evt) {
    var msg = this.add_to_cart_error_msg();

    if (msg) {
      evt.stop();
      alert(msg);
      return false;
    }

  },


  onclick: Event.delegate({
    '.pp-buy-button input': function (e) { this.add_to_cart_button_clicked(e) }
  })

});


// Simple case: single product, no variations.
// - DOM: There should be only a single availability notice.
var BuyBehaviorSingle = Behavior.create(BuyBehaviorBase, {

  current_availability: function () {
    // Exactly one availability notice in DOM
    return this.AVAILABILITY_STATUS_CODES.find( function (s) {
      return this.elements_availability_notification(s).length;
    }, this);
  }

});


var Price = Class.create({

  initialize: function (x) {
    if (Object.isNumber(x)) {
      this.p = x;
    } else {
      this.p = this._parse(x);
    }
  },

  to_int: function () {
    return this.p;
  },

  to_str: function () {
    ps = this.p.toString();
    while (ps.length < 3) {
      ps = '0'+ps;
    }
    var euros = ps.substring(0, ps.length-2);
    var cents = ps.substring(ps.length-2);
    var res = euros;
    if (cents != '00') res += ','+cents;
    res += ' \u20ac';
    return res;
  },

  _parse: function (pt) {
    // smx_sm: strip off leading 0
    if(pt.substr(0,1) == "0")
        pt = pt.substr(1);

    // smx_sm: add tailing 0 if necessary
    var komma = pt.indexOf(",");
    if(komma != -1)
    {
        var cents = pt.substring(komma+1,pt.length);
        if(cents.length == 1)
            pt = pt + "0";
    }
    else
        pt = pt + ",00";

    var np = parseInt(pt.gsub(/[\.,]/, ''));
    return np;
  }

});


var VariationList = Class.create({

  price: function () {
    var ci = this._current_item();
    if (ci) {
      return ci.price();
    } else {
      return this._cheapest_item().price();
    }
  },

  price_uvp: function () {
    var ci = this._current_item();
    if (ci) {
      return ci.price_uvp();
    } else {
      return this._cheapest_item().price_uvp();
    }
  },

  availability: function () {
    var ci = this._current_item();
    if (ci)
      return ci.availability();
  },

  // smx_sm: added
  oxid: function () {
    var ci = this._current_item();
    if (ci)
      return ci.oxid();
    else
      return '';
  },
  reffield: function () {
    var ci = this._current_item();
    if (ci)
      return ci.reffield();
    else
      return '';
  },
  // smx_sm: end

  update_display_prices: function () {
    this.items.invoke('update_display_price', this.price());
  },

  _cheapest_item: function () {
    var min_item;
    var min_price;
    this.items.each(function (item) {
      if (!min_item || (item.price().to_int() < min_price)) {
        min_item = item;
        min_price = min_item.price().to_int();
      }
    });
    return min_item;
  }

});


var VariationListSelect = Class.create(VariationList, {

  initialize: function (select_elem) {
    this.select_elem = select_elem;

    this.items_by_index = {};
    $A(this.select_elem.options).each(function (o, i) {
      if (o.value != 'not_selected')
        this.items_by_index[i] = new VariationListItemSelect(o);
    }, this);
    this.items = $H(this.items_by_index).values();
  },

  _current_item: function () {
    return this.items_by_index[this.select_elem.selectedIndex];
  }

});


var VariationListRadio = Class.create(VariationList, {

  initialize: function (form, group_id) {
    this.gid = group_id;
    this.items = form.getInputs(null, 'optiongroup-'+group_id).collect(function (input) {
      if (input.type.toLowerCase() == 'hidden') {
        return new VariationListItemHidden(input);
      } else {
        return new VariationListItemRadio(input);
      }
    });
  },

  is_empty: function () {
    return this.items.length == 0;
  },

  // smx_sm: added for writing oxid to hidden field
  oxid: function () {
    return this._current_item().oxid();
  },
  reffield: function () {
    return this._current_item().reffield();
  },
  // smx_sm: end

  img_url: function (size_id) {
    var ci = this._current_item();
    if (ci.img_url) return ci.img_url(size_id);
  },

  description: function () {
    var ci = this._current_item();
    if (ci.description) return ci.description();
  },

  // smx_sm: added for adding the selected size to the title string (needed for the basket/order logic)
  size_choice: function () {
    var ci = this._current_item();
    if (ci.size_choice) return ci.size_choice();
  },
  get_variation: function () {
    var ci = this._current_item();
    if (ci.get_variation) return ci.get_variation();
  },
  // smx_sm: end

  zoom_url: function () {
    var ci = this._current_item();
    if (ci.zoom_url) return ci.zoom_url();
  },

  group_id: function () { return this.gid; },

  add_to_cart_error_msg: function () {
    if (this._current_item().visible && !this._current_item().visible())
      return 'Bitte erst die gewünschte Größe wählen!';
  },

  activate_default_item: function () {
    var first_avail_item = this.items.find(function (item) {
      return item.visible() && (item.availability() > 1);
    });
    if (first_avail_item) {
      this.items.invoke('activate', false);
      first_avail_item.activate(true);
    }
  },

  _current_item: function () {
    return this.items.find(function (item) {
      return item.is_selected();
    }) || this.items.first();
  }

});


var VariationListItem = Class.create({

  VARIATION_CODE_PARTS: {'oxid':0, 'availability':1, 'price':2, 'reffield':3, 'uvp':4},

  price: function () {
    var txt = this._parse_code(this._code(), 'price');
    return new Price(txt);
  },

  price_uvp: function () {
    var txt = this._parse_code(this._code(), 'uvp');
    if (txt) return new Price(txt);
  },

  availability: function () {
    return parseInt(this._parse_code(this._code(), 'availability'));
  },

  // smx_sm: added
  oxid: function () {
    return this._parse_code(this._code(), 'oxid');
  },
  reffield: function () {
    return this._parse_code(this._code(), 'reffield');
  },
  // smx_sm: end

  _parse_code: function (vc, part) {
    var pos = this.VARIATION_CODE_PARTS[part];
    if (vc && pos > -1) return $A(vc.split('-'))[pos];
  }

});


var VariationListItemSelect = Class.create(VariationListItem, {

  initialize: function (elem) {
    this.elem = elem;
  },

  update_display_price: function (base_price) {
    this.elem.text = this._update_price_text(this.elem.text, new Price(this.price().to_int()-base_price.to_int()));
  },

  _update_price_text: function (t, p) {
    var res = t.gsub(/ \([^)]+\)$/, '');
    if (p.to_int() != 0) {
      res += ' (';
      if (p.to_int() >= 0) res += '+';
      res += p.to_str()+')';
    }
    return res;
  },

  _code: function () {
    return this.elem.value;
  }

});


var VariationListItemRadio = Class.create(VariationListItem, {

  initialize: function (input) {
    this.elem_input = input;
    this.elem_li = this.elem_input.up('li');
    this.elem_price = this.elem_li.down('.pp-choice-price');
    this.elem_img = this.elem_li.down('.pp-choice-img img');
    this.elem_description = this.elem_li.down('.pp-choice-description strong');
    // smx_sm: added
    this.elem_variation = this.elem_li.down('.pp-choice-description .pp-variation');
    this.elem_sizechoice = this.elem_li.down('.pp-choice-description .pp-size');
    // smx_sm: end
    this.elem_link = this.elem_li.down('a');
  },

  is_selected: function () {
    // multiple radio buttons may be checked if they are detached from the document
    return this.elem_input.checked && this.visible();
  },

  activate: function (b) {
    this.elem_input.checked = b;
  },

  update_display_price: function (base_price) {
    if (this.is_selected()) {
      this.elem_price.update('im Set enthalten');
    } else {
      var p = new Price(this.price().to_int()-base_price.to_int());
      var price_txt = '';
      if (p.to_int() > 0) price_txt += '+';
      price_txt += p.to_str();
      this.elem_price.update('<strong>'+price_txt+'</strong> zum Set');
    }
  },

  img_url: function (size_id) {
    var url = this.elem_img.src;
    if (size_id) {
      var rer = url.match(/(.+\/)([^\/]+\/)([^\/]+)_[^_]*\.jpg$/);
      if(!rer)
      {
          return "";
      }
      var base_path = rer[1];
      var size_path = rer[2];
      var base_filename = rer[3];

      var new_size_path = size_path;
      //if (size_path != 'images/') {
      if (size_path != 'img/') {
        if (size_id == 'th') {
          new_size_path = '0/';
        } else {
          new_size_path = size_id+'/';
        }
      }

      // TEST
      if (size_id == 'th') {
        //base_filename = base_filename.replace(/_img1/g, "");
      }

      var new_size_suffix = '_'+size_id+'.jpg';

      //alert(url + "\n" + base_path + new_size_path + base_filename + new_size_suffix);

      url = base_path + new_size_path + base_filename + new_size_suffix;
    }
    return url;
  },

  description: function () {
    return this.elem_description.innerHTML;
  },

  get_variation: function () {
      if(this.elem_variation)
        return this.elem_variation.innerHTML;
      return '';
  },

  // smx_sm: added
  size_choice: function () {
    if(this.elem_sizechoice)
        return this.elem_sizechoice.innerHTML;
    return '';
  },
  // smx_sm: end

  zoom_url: function () {
      // TODO: wieder anpassen fuer Live-Server!
    //return '/ee4/'+this.elem_link.href.split('/').last();
    return 'http://www.bergzeit.de/'+this.elem_link.href.split('/').last();
  },

  visible: function () {
    return this.elem_li.visible() && this.elem_input.form;
  },

  _code: function () {
    return this.elem_input.value;
  }

});


var VariationListItemHidden = Class.create(VariationListItem, {

  initialize: function (input) {
    this.elem_input = input;
  },

  is_selected: function () {
    return true;
  },

  update_display_price: function (base_price) {
    // obviously not necessary
  },

  _code: function () {
    return this.elem_input.value;
  }

});


// Abstract class
// - updates product price (but depends on an abstract method).
// - updates availability notice.
var BuyBehaviorChoices = Behavior.create(BuyBehaviorBase, {

  elements_price: function () {
    return this.element.select('.pp-price strong');
  },

  update_price: function (p) {
    if (p)  {
        // smx_sm: added hook for hidden price field update
        updateHiddenPrice(p.to_int());
        // smx_sm: end
        this.elements_price().invoke('update', p.to_str());
    }
  },

  update_price_uvp: function (actual_price, uvp) {
    this.elements_price_uvp().each(function (elem) {
      if (uvp && (uvp.to_int() != actual_price.to_int())) {
        elem.update('statt '+uvp.to_str()+'*');
      } else {
        elem.update('bei bergzeit.de');
      }
    });
  },

  // smx_sm: not used, see function update() below
  update_oxid: function (s, r) {
    if(s != '' && s != "not_selected")
    {
        var hfield = $(r);
        hfield.value = s;
    }
  },
  // smx_sm: end

  update_availability: function (avail_status) {

    // hide all notifications
    this.AVAILABILITY_STATUS_CODES.each( function (s) {
      this.elements_availability_notification(s).invoke('hide');
    }, this);

    // display notification for current status, if any
    var elems = this.elements_availability_notification(avail_status);
    if (elems) elems.invoke('show');

  },

  update: function ($super) {
    $super();

    this.update_availability(this.current_availability());

    var cp = this.current_price();
    this.update_price(cp);
    this.update_surcharges(cp);
    this.update_price_uvp(cp, this.current_price_uvp());


    // smx_sm: added - not necessary since the oxid ("variant_anid")
    // is stripped off in PHP (module brg_cmp_basket.php, method tobasket())
    /*
    var q = this.current_oxid();
    var r = this.current_reffield();
    this.update_oxid(q, r);
    */
  }

});


// Multiple variations for one product
// - updates prices in variation select box
var BuyBehaviorSelect = Behavior.create(BuyBehaviorChoices, {

  initialize: function ($super) {
    this.varList = new VariationListSelect(this.element_select_variation());
    $super();

    // IE (at least up to IE7) does not bubble the onchange event
    // Therefore it needs to be attached manually
    this.element_select_variation().observe('change', this.update.bindAsEventListener(this));
  },

  element_select_variation: function () {
    return this.element.down('.pp-variation');
  },

  elements_price_uvp: function () {
    return this.element.select('.pp-price .pp-rebate');
  },

  current_availability: function () {
    return this.varList.availability();
  },

  current_price: function () {
    return this.varList.price();
  },

  current_price_uvp: function () {
    return this.varList.price_uvp();
  },

  // smx_sm: added
  current_reffield: function () {
      return this.varList.reffield();
  },
  current_oxid: function () {
      return this.varList.oxid();
  },
  // smx_sm: end

  update_surcharges: function (base_price) {
    this.varList.update_display_prices(base_price);
  },

  flash_select_variation: function () {
    var elem = this.element.down('.pp-variation-container');
    if (elem) new Effect.Highlight(elem, {startcolor: '#c12600'});
  },

  add_to_cart_button_clicked: function ($super, evt) {
    if (!this.current_availability()) {
      evt.stop();
      alert('Bitte erst die gewünschte Produktvariante wählen!');
      this.flash_select_variation();
      return false;
    }
    $super(evt);
  }

});


var BuyBehaviorKonfigurator = Behavior.create(BuyBehaviorChoices, {

  ALLOWED_OPTION_GROUPS: $A([1,2,3,4]),

  initialize: function ($super) {
    this.optGroups = $A();
    this.ALLOWED_OPTION_GROUPS.each(function (gid) {
      var og = new VariationListRadio(this.element, gid);
      if (!og.is_empty()) this.optGroups.push(og);
    }, this);

    // force update
    document.observe('productpage:activate_default_item', this.activate_default.bindAsEventListener(this));
    $super();
  },

  elements_price_uvp: function () {
    return this.element.select('.pp-price .pp-uvp');
  },

  elements_sizes_product_img: function (group_id) {
    var res = $A();
    var pic_desc = $A();
    pic_desc.push($$('#pp-hero-'+group_id+' img').first());
    if (group_id == 1) {
      pic_desc.push('img1');
    } else {
      pic_desc.push('th');
    }
    res.push(pic_desc);
    pic_desc = $A();
    pic_desc.push($$('#pp-summary-choice-'+group_id+' img').first());
    pic_desc.push('th');
    res.push(pic_desc);
    return res;
  },

  element_description: function (group_id) {
    return $$('#pp-summary-choice-'+group_id+' p').first();
  },

  elements_zoom: function (group_id) {
    return [$('pp-hero-'+group_id+'-zoom'), $('pp-hero-'+group_id)];
  },

  current_availability: function () {
    return this.optGroups.min(function (og) {
      return og.availability();
    });
  },

  current_price: function () {
    return new Price(this.optGroups.inject(0, function (sum, og) {
      return sum + og.price().to_int();
    }));
  },

  current_price_uvp: function () {
    var sum_uvp = this.optGroups.inject(0, function (sum, og) {
      var uvp = og.price_uvp();
      if (Object.isNumber(sum) && uvp) {
        return sum + og.price_uvp().to_int();
      } else {
        return null;
      }
    });
    if (sum_uvp) return new Price(sum_uvp);
  },

  add_to_cart_error_msg: function ($super) {
    var og = this.optGroups.find(function (og) {
      return og.add_to_cart_error_msg();
    });
    if (og) {
      return og.add_to_cart_error_msg();
    } else {
      return $super();
    }
  },

  update_description: function () {
    this.optGroups.each(function (og) {
      var desc = og.description();
      if (desc)
      {
        // smx_sm: added to update hidden persparam fields
        var selsize = og.size_choice();
        if(selsize)
        {
            desc += " " + selsize;
        }
        else{
            // smx_sm: add variation
            var tst = og.get_variation();
            if(tst != '' && desc.indexOf(tst) < 0)
                desc += " - " + tst;
        }
        updateHiddenSelectedTitle(og.group_id(), desc, og.oxid());
        // smx_sm: end

        this.element_description(og.group_id()).innerHTML = desc;
      }
    }, this);
  },

  update_surcharges: function (base_price) {
    this.optGroups.invoke('update_display_prices', base_price);
  },

  update_images: function () {
    this.optGroups.each(function (og) {
      this.elements_sizes_product_img(og.group_id()).each(function (d) {
        var elem = d[0];
        var size_code = d[1];
        if (elem && og) {
          var url = og.img_url(size_code);
          if (url) {
              //alert(url);
              url = url.replace(/\/img([0-9a-z])/g, "/$1");
              elem.src = url;

                var desc = og.description();
                  if (desc)
                  {
                    // smx_sm: added to update hidden persparam fields
                    var selsize = og.size_choice();
                    if(selsize)
                    {
                        desc += " " + selsize;
                    }
                    else{
                        // smx_sm: add variation
                        var tst = og.get_variation();
                        if(tst != '' && desc.indexOf(tst) < 0)
                            desc += " - " + tst;
                    }
                    elem.title = desc;
                    elem.alt = desc;
                  }

          }
        }
      });
    }, this);
  },

  update_zoom: function () {
    this.optGroups.each(function (og) {
      var url = og.zoom_url();
      if (url) this.elements_zoom(og.group_id()).each(function (elem) {
        // smx_sm: show top image if valid article / url (may be initially invisible if no option selected)
        if(url.indexOf("#") < 0) {
            elem.show();
        }
        // smx_sm: end
        elem.href = url.replace(/detailspopup/g, "moredetails");
      });
    }, this);
  },

  update: function ($super) {
    $super();
    this.update_images();
    this.update_description();
    this.update_zoom();
  },

  activate_default: function (evt) {
    var tog = evt.memo;
    this.optGroups.find(function (og) {
      if (og.group_id() == tog) {
        og.activate_default_item();
        return true;
      } else {
        return false;
      }
    });
    this.update();
  },

  onclick: function ($super, evt) {
    Event.delegate({
      '.pp-choice-radio input': this.update.bind(this),
      '.pp-choices a': function (e) {
        open(e.findElement('a').href, 'details_info', 'resizable=yes,status=no,scrollbars=yes,menubar=no,width=680,height=400');
        e.stop();
      }
    })(evt);
    $super(evt);
  }

});


var KonfiguratorChoiceBehavior = Behavior.create({

  initialize: function () {
    // this.sizes_to_items will be set to null if there are elements without a size
    this.sizes_to_items = this.gather_sizes(this.element);

    if (this.sizes_to_items) {
      var list_sizes = $H(this.sizes_to_items).keys().sort();
      this.select_elem = this.insert_select(this.element.down('h2'), list_sizes);
      this.select_elem.observe('change', this.update.bindAsEventListener(this));
    }
    this.update();
  },

  gather_sizes: function (elem) {
    var res = {};
    elem.select('li').each(function(item) {

      // res is either a hash or null
      // if it is a hash we should build the size lookup table
      // if it is null we should abort
      if (!res) return;

      // check whether each product has a size
      // abort building the lookup table if it has not
      var elem_size = item.down('.pp-size');
      if (!elem_size) {
        res = null;
        return;
      }

      // the product has a size, add it to the size lookup table
      var isize = elem_size.innerHTML;
      res[isize] = res[isize] || $A();
      res[isize].push(item);

    });
    return res;
  },

  insert_select: function (elem, sizes) {
    var select_elem = new Element('select', {size: 1}).update(
      new Element('option', {value: -1}).update('Bitte Größe wählen...')
    );
    sizes.each(function(txt, i) {
      select_elem.insert(new Element('option', {value: i}).update(txt));
    });
    elem.appendChild(
      DOM.Builder.create('span', null, ['\u00a0\u00a0\u00a0\u00a0\u00a0', select_elem])
    );
    return select_elem;
  },

  update: function () {
    if (this.sizes_to_items) {

      // hide everything
      // display: none and subsequent display: block produces strange results
      // on IE6. Removing and reattaching those child nodes works.
      var elem_ul = this.element.down('ul');
      this.element.select('li').each(function (elem) {
        elem_ul.removeChild(elem);
      });
      this.element.down('p').hide();

      var size_txt = this.select_elem.options[this.select_elem.selectedIndex].innerHTML;
      if (this.sizes_to_items[size_txt]) {
        // show items according to the selected size
        this.sizes_to_items[size_txt].each(function (elem) {
          elem_ul.appendChild(elem);
        });
        var opt_group = parseInt(this.element.down('input').name.split('-').last());
        this.element.fire('productpage:activate_default_item', opt_group);
      } else {
        // no size selected, show notice
        this.element.down('p').show();
      }

    } else {
      var opt_group = parseInt(this.element.down('input').name.split('-').last());
      this.element.fire('productpage:activate_default_item', opt_group);
    }
  }

});


Event.addBehavior({

  // rule does not match Konfigurator
  '.pp-buy form': attachBuyBehavior,

  // Konfigurator
  '#productpage > form': BuyBehaviorKonfigurator,
  '.pp-choices': KonfiguratorChoiceBehavior,

  '.pp-hero-container > a:click' : function (e) {
    //smx_ta ie9 fix
    //open(e.findElement('a').href, 'zoom', 'status=yes,scrollbars=yes,menubar=no,width=750,height=750');
    open(e.findElement('a').getAttribute("url"), 'zoom', 'status=yes,scrollbars=yes,menubar=no,width=750,height=750');
    e.stop();
  },

  '.pp-thumbs a:mouseover' : function (e) {
    // smx_sm: changed:
    //$('pp-hero').src = e.findElement('a').firstDescendant('img').src;
    $('pp-hero').src = e.findElement('a').firstDescendant('img').getAttribute("bigimg");
    e.stop();
  },

  '.add-to-cart-flash' : function () {
    new Effect.Highlight($$('.add-to-cart-flash').first(), {startcolor: '#ffff00'});
  }

});


