var Shop = Component.create({
  
  run: function() {
    if (Cookie.get('basket') == 'true') {
      this.addName('withBasket', this.element)
      this.basket.request('GET', '/items.html');
      this.basket.addName('busy', this.basket.contents);
    }
  },
  
  handleError: function(element) {
    if (/dialog/.test(element.className || ''))
      this.dialogs.append(element);
  }
});

Shop.define('login', {
    
  handleResponse: function(status) {
    if (status == 200)
      window.location.reload();
  },
  
  onSubmitElement: function(event) {
    event.preventDefault();
    this.request('POST', this.element.action, this.getParam());
  },
  
  getParam: function() {
    var o = {};
    o[this.password.name] = this.password.value;
    o[this.user.name]     = this.user.value;
    return o;
  }
});

Shop.define('dialogs', {

  append: function(element) {
    element.style.opacity = 0;
    this.insert(element);
    new Appearance(element);
  }
}).define('dialog', {

  run: function() {
    if (!this.busy && (this.element.id != 'inspector')) {
      this.waitAndRemove();
    }
  },
  
  update: function(notice) {
    if (notice.progress) {
      this.progress.innerHTML = notice.progress;
    }
    if (notice.progress == 100) {
      clearInterval(this.interval);
      this.waitAndRemove();
      this.request('DELETE', this.path.href);
    }
  },
  
  remove: function() {},
  
  waitAndRemove: function() {
    var element = this.element;
    
    setTimeout(function() {
      new FadeRemove(element);
    }, 3000);
  }
});

Shop.define('progressMeter', {

});

Shop.define('basket', {
  
  prepare: function() {
    this.count = 0;
  },
  
  handleElement: function(element) {
    if (element.id == 'basket')
      this.replace(element);
  },
  
  remove: function() {
    Cookie.set('basket', 'false');
    new Fade(this.element, function() {
      shop.removeName('withBasket');
    });
  },
  
  replace: function(element) {
    this.element.parentNode.replaceChild(element, this.element);
    shop.basket = this.context.insert(element).basket;
    
    if (shop.basket.count == 0)
      shop.basket.remove();
  }
});

Shop.define('basketItem', {

  run: function() {
    this.basket.count++;
  },

  onClickDestroy: function() {
    this.basket.request('DELETE', this.destroy.href);
  }
});

Shop.define('removedItem', {
  
  run: function() {
    new FadeRemove(this.element, function() {
      if (--shop.basket.count == 0) {
        shop.basket.remove();
      }
    });
  }
});

Shop.define('createdItem', {
  
  run: function() {
    if (!shop.withBasket) {
      shop.addName('withBasket', shop.element);
      Cookie.set('basket', 'true');
    }
    new Appearance(this.element);
  }
});


Shop.define('uploads', {
  
  run: function() {
    if (this.uploader)
      this.target = this.uploader.element;
  },
  
  uploadFrom: function(upload) {
    if (!this.id) {
      var action = upload.form.action;
      
      this.id = this.createId();
      
      upload.form.action += "&X-Progress-ID=" + this.id;
      
      upload.form.submit();
      
      upload.form.action = action;

      this.uploading = upload;
      
      this.requestProgress();
    }
  },
  
  requestProgress: function() {
    this.request('GET', '/progress.json?id=' + this.createId() + '&X-Progress-ID=' + this.id);
  },
  
  handleResponse: function(status, text) {
    var object = eval("(" + text + ")");
    
    if (object.state == 'done' || object.state == 'failed') {
      new Fade(shop.progressMeter.dialog.element, function() {
        shop.progressMeter.dialog.element.style.display = 'none';
      });
      return this.id = null;
    }
    
    if (shop.progressMeter.dialog.element.style.display == 'none') {
      shop.progressMeter.dialog.element.style.display = '';
      new Appearance(shop.progressMeter.dialog.element);
    }      
    
    if (object.received && object.size)
      shop.progressMeter.element.innerHTML = Math.floor((object.received / object.size) * 100);
    
    var o = this;
    setTimeout(function() {
      o.requestProgress();
    }, 200);
  },
  
  createId: function() {
    var id = "";for (i=0; i<10; i++) id += Math.floor(Math.random() * 16).toString(16);
    return id;
  },
    
  onLoadTarget: function() {
    if (this.uploading) {
      this.uploading.update(this.uploader.getContent());
      this.uploading = false;
    }
  }
});

Shop.define('uploader', {
  
  getContent: function() {
    return this.getDocument().body.innerHTML;
  },
  
  getDocument: function() {
    return this.element.contentDocument || this.element.contentWindow.document;
  }
});

Shop.define('upload', {
  
  run: function() {
    this.form = this.form || this.element;
    
    if (/firefox\/3/i.test(navigator.userAgent)) {
      this.file.style.right = null;
      this.file.style.left  = 0;
    }
  },
  
  update: function(text) {
    if (this.image) {
      this.element.removeChild(this.image);
    }
    this.image = document.loadElement(text).getElementsByTagName('img')[0];
    this.element.appendChild(this.image);

    this.removeName('busy');
  },
  
  onClickElement: function() {
    // Open the file browser (safari-only)
    this.file.click();
  },
  
  // onClickFile: function() {
  //   alert('file!');
  // },
  
  onChangeFile: function() {    
    if (this.image) {
      this.addName('busy', this.element);
      this.uploads.uploadFrom(this);
      this.file.value = '';
    }    
  }
});


Shop.define('collection', {
  
  prepare: function() {
    this.items = [];
  },
  
  onClickAdd: function(event) {
    if (this.add.href) {
      this.request('POST', this.add.href);
    }
  },
  
  handleElement: function(element) {
    var item = this.context.insert(element).item;
    
    if (item) {
      this.element.appendChild(item.element);
      new Appearance(item.element);

      this.setNames();
    }    
  },
  
  removeItem: function(item) {
    var collection = this;
    
    collection.items.splice(item.position, 1);
    
    for (var i = item.position; i < this.items.length; i++) {
      this.items[i].position--;
    }
        
    new FadeRemove(item.element, function() {
      collection.setNames();
    });
  },
  
  moveForward: function(i) {alert(this.items.length);
    var a = this.items[i], b = this.items[i + 1];
        
    this.element.insertBefore(b.element, a.element);
        
    a.position++;
    b.position--;
    
    this.items[i]     = b;
    this.items[i + 1] = a;
    
    this.setNames();
  },
  
  removeItems: function() {
    for (var i = 0; i < this.items.length; i++)
      this.element.removeChild(this.items[i].element || this.items[i]);
    this.items = [];
  },
  
  setNames: function() { return;
    if (this.items.length > 0) {
      this.setName('first', this.items[0].element);
      this.setName('last',  this.items[this.items.length - 1].element);
    }
  }
});

Shop.define('item', {
  
  run: function() {
    if (!this.collection)
      return;
    
    this.collection.items.push(this);
    this.position = this.collection.items.length;
    
    this.collection.setNames();
  },
  
  notifyWithCollection: function(component, container) {
    if (container)
      this.collection = this.collection || component;
  },
  
  remove: function() {
    this.collection.removeItem(this);
  },

  onClickBack: function(event) {
    if (this.position > 0) {
      this.collection.moveForward(this.position - 1);
    }
  },
  
  onClickForward: function(event) {
    if (this.position < this.collection.items.length - 1) {
      this.collection.moveForward(this.position);
    }
  },
  
  onClickDestroy: function(event) {
    if (confirm('Are you sure?')) {
      this.request('DELETE', this.destroy.href);
    }
  }
});

Shop.define('toPreview', {
  
  onClickElement: function(event) {
    this.interface.overlay.open();
  }  
});

Shop.define('overlay', {

  onClickElement: function(event) {
    this.hide();
  },
    
  open: function() {

    this.addName('overlayed', document.documentElement);
    this.addName('fixed', document.documentElement);

    this.interface.preview.makeCentered();

    var effect = new Effects.Opacity(this.element, { duration: 200 });
    
    effect.setStyle(this.element, 'opacity', 0);
    effect.custom(0, 0.6);
  },
  
  hide: function() {
    if (this.preview) this.preview.remove();
    
    var o = this;
    new Effects.Opacity(this.element, { duration: 200, onComplete: function() { o.removeName('overlayed'); o.removeName('fixed') } }).custom(0.6, 0);    
  }
});


Shop.define('preview', {
  
  onClickClose: function() {
    this.interface.overlay.hide();
  },
  
  makeCentered: function() {
    this.element.style.marginLeft = '-' + (this.element.offsetWidth / 2) + 'px';
    this.element.style.marginTop  = '-' + (this.element.offsetHeight / 2) + 'px';
  }
});

Shop.define('icon', {
  onClickElement: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue  = false;
      event.cancelBubble = true;
    }
  }
});

Shop.define('slideshow', {
  run: function() {
    var elements = this.element.getElementsByTagName('li');

    if (elements.length > 1) {
      this.items    = elements;
      this.index    = 0;
      this.selected = this.items[this.index];
      
      var object = this;
      this.inerval = setInterval(function() { object.onInterval() }, 5000);
    }
  },
  
  onClickDestroy: function(event) {
    new FadeRemove(this.element);
    for (var i = 0; i < page.articles.length; i++)
      page.articles[i].setModified();
    clearInterval(this.interval);
  },
  
  onInterval: function() {
    this.previous = this.selected;
    var selected = this.items[ this.index = ((this.index + 1) % this.items.length) ];

    this.removeName('selected');
    this.addName('selected', selected);
    
    this.fade(this.previous);
  },
  
  fade: function(element) {
    var slideshow = this;
    this.addName('fading', element);    

    new Effects.Opacity(element, { duration: 600, onComplete: function() {
      slideshow.removeName('fading');
      element.style.opacity    = null;
      element.style.filter     = null;
      //element.style.visibility = null;
    } }).custom(1, 0);  
    
  }
});

Shop.define('productOptions', {
    
  append: function(element) {
    element.style.opacity = 0;
    this.insert(element);
    page.context.insert(element);
    new Appearance(element);
  }
}).define('productOption', {
  
  run: function() {
    if (this.optionValue) {
      this.optionValue.element.checked = true
      this.optionValue.onClickElement();
    }
  }
  
}).define('optionValue', {
  
  onClickElement: function() {
    this.productSidebar.submit(true);
  }
});

Shop.define('productSidebar', {
  
  onClickAdd: function() {
    this.submit(false);
  },
  
  update: function(object) {
    this.calculatedPrice.innerHTML = object.price;
  },
  
  handleElement: function(element) {
    if (element.id == 'basket')
      return shop.basket.replace(element);
  },
  
  submit: function(preview) {
    var params = this.serialize(), name = 'values[option_value_ids][]';
    
    var list = this.element.elements, values = [];
    
    for (var i = 0; i < list.length; i++)
      if (list[i].checked)
        values.push(list[i].value);
    
    params[name] = values;
    var action = this.element.action;
    
    if (preview) {
      action = action.replace(/html/, 'json');
      params.preview = true;
    }
    this.request('POST', action, params);
  }
});



var shop;
document.loadEvents.push(function() { shop = Shop.load(this.documentElement); })