var Shop = Component.create({
  
  run: function() {
    // if the cookie says we have a basket then fetch the basket from server
    // the only page that we do not fetch the basket from is the checkout page
    if (Cookie.get('withBasket') == 'true' && !/\/checkout\.html/.test(window.location.href)) {
      this.addName('withBasket', document.body);
      this.requestBasket();
    }

    var param;
    if (param = window.location.toString().match(/currency=(GBP|EUR|USD)/))
      Cookie.set('currency', param[1]);
    
    if (this.currency = Cookie.get('currency')) {
      document.documentElement.className = document.documentElement.className.replace('GBP', '');
      this.addName(this.currency, document.documentElement);
    }
    
  },
  
  onClickToBasket: function(event) {
    var whichCollection = document.getElementById('whichCollection');
		var instructions = "";
		if(whichCollection){
			if(!whichCollection.value){
				alert("This item is for collection only and requires that you select one of our galleries as a collection point.\nPlease read the information in the box above the 'Add to Basket' button.\nAny enquiries? Please call 0845 644 5334 or email orders@artrepublic.com.");
				return;
			}
			instructions = "Collect from "+whichCollection.value;
		}
    this.request('POST', this.toBasket.href, {instructions: instructions});
  },
    
  setCurrency: function(id) {
    var element = this.document.documentElement;
    
    element.className = element.className.replace(/GBP|EUR|USD/g, '');
    
    this.addName(id, element);
    Cookie.set('currency', id);
  },
  
  handleElement: function(element) {
    if (element.id == 'basket')
      this.handleBasket(element);
  },
  
  requestBasket: function() {
    this.addName('loading', this.basket.element);
    this.request('GET', '/basket.html');
  },
  
  handleBasket: function(element) {
    this.basket.replace(element);

    if (this.basket.size == 0)
      this.removeBasket();
    else if (Cookie.get('withBasket') != 'true')
      this.showBasket();
  },
  
  showBasket: function() {
    this.addName('withBasket', this.document.body);
    Cookie.set('withBasket', 'true');
    
    this.basket.element.opacity = 0;
    new Appearance(this.basket.element);
  },
  
  hideBasket: function() {
    this.removeName('withBasket');
    Cookie.set('withBasket', 'false');
  },
  
  removeBasket: function() {
    if (IE6)
      this.hideBasket();
    else
      new Effects.Opacity(this.basket.element, {
        onComplete: function() {
          shop.hideBasket();
        }
      }).custom(1, 0);    
  },
  
  handlePanel: function(element) {
    this.panels.append(element);
  },
  
  handleAdvert: function(element) {
    this.adverts.append(element);
  },
  
  handleFrame: function(element) {
    this.frames.append(element);
  },
  
  handleZoomedImage: function(element) {
    this.zoomedImages.append(element);
  },
  
  handleError: function(element) {
    if (/dialog/.test(element.className || '')) {
      this.dialogs.append(element);
      
      if (this.basket)
        this.removeBasket();
    }
  },
  
  notifyWithBasket: function(basket) {
    this.basket = basket;
  }
});

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

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

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

Shop.define('zoomedImages', {
  
  prepare: function() {
    this.images = [];
  },
  
  notifyWithZoomedImage: function(image) {
    this.images.push(image);
  },
  
  append: function(element) {
    element.style.opacity = 0;
    this.insert(element);
    new Appearance(element);
  }
});

var Basket = Shop.define('basket', {
  
  prepare: function() {
    this.size = 0;
  },
  
  run: function() {
    if (this.element.className.indexOf('minimised') > -1)
      this.minimised = this.element;
  },
  
  setPrintsWidth: function(n) {
    this.first.width = n * 147;
  },
  
  onClickElement: function(event) {
    if (this.minimised && ((event.target || event.srcElement) != this.minimise))
      this.onClickMinimise(event);
  },
  
  onClickMinimise: function(event) {
    if (this.minimised) {
      this.removeName('minimised');
      Cookie.set('minimised', 'false');
    } else {
      this.addName('minimised', this.element);
      Cookie.set('minimised', 'true');
    }
  },
  
  onClickOldbutton: function(event) {
    this.addName('checkingOut', this.element);
    this.toCheckout.submit();
  },
  
  onUnloadWindow: function(event) {
    this.removeName('checkingOut');
  },
  
  replace: function(element) {
    this.element.parentNode.replaceChild(element, this.element);
    this.context.insert(element);
  },
  
  notifyWithItem: function(item) {
    if (item.element != this.last)
      this.size++;
  },
  
  notifyWithRemoval: function() {
    if (--this.size == 0) {
      this._interface.removeBasket();
    }
    this.setPrintsWidth(this.size);
  }
});

Basket.define('item', {

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

Basket.define('removed', {

  run: function() {
    var basket = this.basket, notifyWithRemoval = function() {
      basket.notifyWithRemoval();
    };
    
    if (IE6) {
      this.remove();
      setTimeout(notifyWithRemoval, 500);
    } else {
      new FadeRemove(this.element, notifyWithRemoval);
    }
  }
});

Basket.define('selected', {

  run: function() {
    new Appearance(this.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) {
      var notice = this;
      this.interval = setInterval(function() { notice.request('PUT', notice.path.href) }, 1000);
    } else if (this.notice || this.error || this.denied) {
      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('uploads', {
  
  run: function() {
    if (this.uploader)
      this.target = this.uploader.element;
  },
  
  uploadFrom: function(upload) {
    if (!this.uploading) {
      upload.form.submit();
      
      if (upload.path)
        this.request('GET', upload.path.href);
      
      this.uploading = upload;
    }
  },
  
  handleElement: function(element) {
    this._interface.dialogs.append(element);
  },
  
  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;
  },
  
  update: function(text) {    
    if (this.image) {
      this.element.removeChild(this.image);
    }
    this.image = document.loadFragment(text).firstChild;
    this.element.appendChild(this.image);

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


Shop.define('currency', {
  onClickElement: function() {    
    this._interface.setCurrency(this.element.id);
  }
});

Shop.define('collection', {
  
  prepare: function() {
    this.items = [];
  },
  
  onClickAdd: function(event) {
    if (this.add.href) {
      this.request('POST', this.add.href);
    }
  },
  
  onClickExpand: function(event) {
    var collection = this;
    
    new AsyncRequest('GET', this.expand.href, {}, {
      handleResponse: function(code, text) {
        if (!text)
          return;

        var node = collection.document.loadFragment(text);
        
        collection.removeItems();
        collection.element.innerHTML = '';

        var contexts = collection.context.loadNode(node);
        
        for (var i = 0; i < contexts.length; i++) {
          contexts[i].components.item.collection = collection;
          contexts[i].run();
        }
        
        collection.element.appendChild(node);
      }
    }).send();
  },
  
  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) {
    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();
    
    var params = {};
    params[b.id.name] = b.id.value;
    
    this.request('PUT', a.path.href, params);
  },
  
  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() {
    if (this.items.length > 0) {
      this.setName('first', this.items[0].element);
      this.setName('last',  this.items[this.items.length - 1].element);
    }
  }
});

var Item = Shop.define('item', {
    
  notifyWithCollection: function(component, container) {
    if (container && ((component.element == this.element.parentNode) || this.element.tagName.toLowerCase() == 'tr')) {
      this.collection = component;
      
      if ((component.element.id == 'panels') || (component.element.id == 'frameStyles')) {
        this.position = component.items.length;
      }
      
      component.items.push(this);
      component.setNames();
    }
  },
  
  remove: function() {
    this.collection.removeItem(this);
  },
  
  onClickToPreview: function(event) {
    this._interface.overlay.open(this.toPreview.href);
  },

  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 (this.collection && confirm('Are you sure?')) {
      this.request('DELETE', this.destroy.href);
    }
  }
});

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

Shop.define('overlay', {

  onClickElement: function(event) {
    this.hide();
  },
  
  handleElement: function(element) {
    if (this.preview) this.preview.remove();
    document.body.appendChild(element);
    
    this.preview = Shop.Components.preview.load(element);
    this.preview._interface = this._interface;
  },
  
  notifyWithPreview: function(preview) {
    this.preview = preview;
    preview.overlay = this;
  },
  
  open: function(url) {
    this.request('GET', url);

    this.addName('overlayed', document.documentElement);
    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') } }).custom(0.6, 0);    
  }
});

Shop.define('preview', {
  
  run: function() {
    this.image = this.element.getElementsByTagName('img')[0];
  },
  
  onLoadImage: function(event) {
    this.setPosition();
  },
  
  onKeyDownDocument: function(event) {
    if (this.image && event.shiftKey)
      this.addName('setFocus', this._interface.element);
    else
      this.removeName('setFocus');
  },
  
  onClickPrintFocus: function(event) {
    this.onClickImage(event);
  },
  
  onClickImage: function(event) {
    if (!this.printFocus || !this.setFocus)
      return;

    event.stopPropagation();

    var point = {
      x: (event.pageX) - this.getPoint().x,
      y: (event.pageY) - this.getPoint().y
    };

    // alert(event.pageY);
    this.focusX.value = Math.round((point.x / this.image.offsetWidth) * 100);
    this.focusY.value = Math.round((point.y / this.image.offsetHeight) * 100);
    

    this.request('PUT', this.focusY.form.action, this.serialize());
    
    this.setPosition();
  },
  
  onKeyUpDocument: function(event) {
    this.removeName('setFocus');
  },
  
  onClickClose: function() {
    this._interface.overlay.hide();
  },
  
  onClickNext: function(event) {
    this._interface.overlay.request('GET', this.next.href);
  },
  
  onClickPrevious: function(event) {
    this._interface.overlay.request('GET', this.previous.href);
  },
  
  onClickToBasketFromPreview: function(event) {
    this._interface.request('POST', this.toBasketFromPreview.href);
    Cookie.set('minimised', 'false');
  },
  
  setPosition: function() {
    if (!this.printFocus)
      return;

    this.printFocus.style.top  = ((parseInt(this.focusY.value) / 100) * this.image.offsetHeight) + 'px';
    this.printFocus.style.left = ((parseInt(this.focusX.value) / 100) * this.image.offsetWidth) + 'px';
  },
  
  getPoint: function() {
    var element = this.image, point = { x: 0, y: 0 };
    
    if (this.element.id == 'preview') {
      point.y += window.pageYOffset;
      point.x += window.pageXOffset;
    }

    do {
      point.y += element.offsetTop  || 0;
      point.x += element.offsetLeft || 0;
      element  = element.offsetParent;
    } while (element);

    return point;
  },
  
  remove: function() {
    this.element.parentNode.removeChild(this.element);
    this._interface.overlay.preview = null;
  }
});

Shop.define('zoomedImage', {
  
  onMouseOverThumb: function(event) {
    this.zoomed.style.display = 'block';
    //this.zoomed.style.marginLeft = '-' + (this.zoomed.offsetWidth / 2) + 'px';
  },
  
  onMouseOutThumb: function(event) {
    this.zoomed.style.display = '';
  }
});

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

    for (var i = 0; i < elements.length; i++) {
      if (i == 0)
        elements[i].className = 'selected';
      else
        elements[i].className = '';
      elements[i].style.opacity = '';
    }

    if (elements.length > 1) {
      this.items    = elements;
      this.index    = 0;
      this.selected = this.items[this.index];
      this.fading   = null;
      
      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.selected = selected;
    
    this.fade(this.previous);
  },
  
  fade: function(element) {
    var slideshow = this;
    this.addName('fading', element);
    this.fading = element; 

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

Shop.define('query', {

  run: function() {
    this.query        = this.element;
    this.defaultQuery = this.element.value;
  },
  
  onFocusQuery: function(event) {
    if (this.query.value == this.defaultQuery)
      this.query.value = '';
  },
  
  onBlurQuery: function(element) {
    if (this.query.value == '')
      this.query.value = this.defaultQuery;
  }
});

Shop.define('applyVoucher', {
    
  onClickToggle: function(event) {
    this.addName('applyingVoucher', this.element);
  },
  
  onSubmitForm: function(event) {
    if (event.preventDefault)
      event.preventDefault();
    event.returnValue = false;
    
    this.send();
  },
  
  onClickSubmit: function() {
    this.send();
  },
  
  send: function() {
    shop.request('POST', this.field.form.action, this.serialize());
  }
});

Shop.define('info', {
  
  prepare: function() {
    this.frames  = [];
    this.options = 0;
  },
  
  notifyWithFrame: function(frame) {
    frame.position = this.frames.length;
    this.frames.push(frame);
  },
  
  notifyWithOption: function(option) {
    option.position = this.options++;

    if (option.position == 0 && !option.element.parentNode.selectedIndex)
      option.element.selected = 'selected';
  }
}).define('option', {
  
  run: function() {
    this.options = this.element;
    while (this.options && (this.options.tagName.toLowerCase() != 'select'))
      this.options = this.options.parentNode;
  },
  
  onChangeOptions: function() {
    if (this.element.selected) {
      this.info.frames[ this.position ].select();
    }
  }
});

Shop.define('frame', {
  
  run: function() {
    if (this.element.className.indexOf('first') > -1) {
      if (this.radio)
        this.radio.checked = true;
      
      this.select();
    }
  },

  onClickRadio: function() {
    if (this.radio.checked)
      this.select();
  },
  
  select: function() {
    var element = document.getElementById('framePrice');
		
    element.innerHTML = this.price.innerHTML;
    
    this._interface.toBasket.href = this.addToBasket.value;

    if (this.frameImage) this._interface.frameImage.src = this.frameImage.value;
    if (this.zoomThumb1 && this._interface.zoomedImages.images[0].thumb) {
			this._interface.zoomedImages.images[0].thumb.src = this.zoomThumb1.value;
    	this._interface.zoomedImages.images[0].zoomed.src = this.zoomImage1.value;
		}
    if (this.zoomThumb2 && this._interface.zoomedImages.images[1].thumb) {
			this._interface.zoomedImages.images[1].thumb.src = this.zoomThumb2.value;
			this._interface.zoomedImages.images[1].zoomed.src = this.zoomImage2.value;
		}


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