﻿Component.create('attributes', {});
Component.create('attribute', {

  serialize: function() {
    var object = {};
    
    if (this.text) {
      for (var i = 0; i < this.text.length; i++) {
        object[this.text[i].element.name] = this.text[i].element.value;
      }
    }
    
    return object;
  },
  
  update: function(values) {
    this.content.update(values);
    this.unassignClass('busy');
  },

  registerText: function(text) {
    this.text = this.text || [];
    this.text.push(text);
  },
  
  onClickContent: function(event) {
    if (event.target && event.target.href) return;
    this.assignWithClass('editing', this.element);
    event.stopPropagation();
  },
  
  onClickToggle: function(event) {
    event.preventDefault();
    
    this.save();
  },
  
  save: function() {
    this.unassignClass('editing');
    this.assignWithClass('busy', this.element);
    this.request('PUT', this.attributes.url.value, this.serialize());
  }
});

Component.create('flag', {
  onClickElement: function(event) {
    var o = {};
    o[this.element.name] = this.element.checked ? 1 : 0;
    this.request('PUT', this.attributes.url.value, o);
  }
});

Component.create('content', {

  update: function(values) {
    var fragment;
    
    for (var prop in values) {
      if (this.attribute[prop] == this.element) {
        fragment = document.loadFragment(values[prop]);
        Component.instancesFor(fragment);
        this.element.innerHTML = '';
        this.element.appendChild(fragment);
        return;
        //return this.element.innerHTML = values[prop];
      }
    }
  }
});

Component.create('text', {
  
  onClickAttribute: function(event) {
    this.element.focus();
  },
  
  onBlurElement: function(event) {
    if (this.attribute.editing || this.element.id == 'region[map]') {
      this.attribute.save();
    }
  },
  
  onKeyDownElement: function(event) {
    if (event.keyCode == 13) {
      event.preventDefault();
      //this.element.blur();
      this.attribute.save();
    }
  }
});

Component.create('blurb', {});
Component.create('footer', {});
Component.create('html', {
	
  initialize: function() {
    if (this.element != document.body) {
      this.name = this.element.name;
      this.editor = new widgEditor(this.element);
      this.element.name = this.name;

      this.frame = this.editor.theIframe;
      this.frame.allowTransparency = true;

      this.body = document.body;
    }
  },
  
  onLoadFrame: function(event) {
    this.document = this.frame.contentDocument || this.frame.contentWindow.document;
    this.assignWithClass(this.attribute._parents.join(' '), this.document.body);
    
  	this.editor.start();
  },
  
  onClickAttribute: function(event) {
    event.stopPropagation();
  },
  
  onClickBody: function(event) {
    if (this.attribute.editing) {
      this.editor.updateWidgInput();
      this.element.value = this.editor.theInput.value;
      this.attribute.save();
    }
  }
});

Component.create('collection', {
  
  registerItem: function(item) {
    this.items = this.items || [];
    if (item.element.parentNode == this.list) {
      this.items.push(item);
    }
  },

  onClickAdd: function(event) {
    event.preventDefault();
    
    if (this.add.href) {
      this.request('POST', this.add.href);
    }
  },
  
  addItem: function(item) {
    
    // Components added during the session should get parent references as normal?
    item.collection = this;
    if (item.image) {
      item.image.uploads = this.uploads;
    }
    
    Effects.appendAppear(item.element, this.list);

    this.registerItem(item);
    this.applyItemClasses();
  },
  
  removeItem: function(item) {
    this.items.splice(this.items.indexOf(item), 1);
    
    Effects.fadeRemove(item.element);
    
    this.applyItemClasses();
  },
    
  moveItemBack: function(item) {
    var i = this.items.indexOf(item);
    
    this.swapItems(i, i - 1);
    this.saveOrder();
  },
  
  moveItemForward: function(item) {
    var i = this.items.indexOf(item);
    
    this.swapItems(i + 1, i);
    this.saveOrder();
  },
  
  saveOrder: function() {
    this.request('PUT', this.order.value, { ids: this.getOrderedIds() });
  },
  
  getOrderedIds: function() {
    var ids = [];
    for (var i = 0; i < this.items.length; i++) ids.push(this.items[i].id.value);    
    return ids.join(' ');
  },
  
  swapItems: function(i, j) {
    this.list.insertBefore(this.items[i].element, this.items[j].element);
    
    var item = this.items[i];
    this.items[i] = this.items[j];
    this.items[j] = item;

    this.applyItemClasses();
  },
  
  applyItemClasses: function() {
    if (this.items.length > 0) {      
      this.unassignClass('first');
      this.unassignClass('last');
      
      this.assignWithClass('first', this.items[0].element);
      this.assignWithClass('last',  this.items[ this.items.length - 1 ].element);
    }
  }
});

Component.create('item', {
  
  remove: function() {
    this.collection.removeItem(this);
  },

  onClickBack: function(event) {
    event.preventDefault();
    this.collection.moveItemBack(this);
  },
  
  onClickForward: function(event) {
    event.preventDefault();
    this.collection.moveItemForward(this);
  },
  
  onClickDestroy: function(event) {
    event.preventDefault();
    
    if (confirm('Are you sure?')) {
      this.request('DELETE', this.destroy.href);
    }
  }
});

Component.create('uploads', {
  
  uploadFrom: function(form, component) {
    if (!this.component) {
      this.component = component;
      this.assignWithClass('busy', component.element);
      form.submit();
    }
  },

  onLoadUploadTarget: function() {
    if (this.component) {
      this.component.respondToFragment(document.loadFragment( this.getDocument().body.innerHTML ));
      this.unassignClass('busy');
      this.component = null;
    }
  },
  
  getDocument: function() {
    return this.uploadTarget.contentDocument || this.uploadTarget.contentWindow.document;
  }
});

Component.create('image', {
  
  replace: function(image) {
    this.element.parentNode.replaceChild(image.element, this.element);
    image.uploads = this.uploads;
  },
  
  onChangeFile: function() {
    this.uploads.uploadFrom(this.file.form, this);
    this.file.value = '';
  }
});


// A rotating list of images.
// The current item is displayed as a block, the others are hidden. On each change, the previous item is faded out over the top of the new one.
Component.create('slideShow', {
  initialize: 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; setInterval(function() { object.onInterval() }, 5000);
    }
  },
  
  onInterval: function() {
    this.previous = this.selected;

    this.unassignClass('selected');
    this.assignWithClass('selected', this.items[ this.index = ((this.index + 1) % this.items.length) ]);
    
    this.fade(this.previous);
  },
  
  fade: function(element) {
    this.assignWithClass('fading', element);    
    var object = this;
    
    new Fx.Opacity(element, { duration: 600, onComplete: function() {
      object.unassignClass('fading');
      element.style.opacity    = null
      element.style.filter     = null;
      //element.style.visibility = null;
    } }).custom(1, 0);  
  }
});

Component.create('root', {});

Component.create('dialog', {
  
  show: function() {
    this.makeCentered();
    this.assignWithClass('on', this.element);
    this.assignWithClass('busy', this.element);
  },
  
  remove: function() {
    this.element.parentNode.removeChild(this.element);
  },
  
  onClickClose: function(event) {
    this.overlay.hide();
  },
  
  makeCentered: function() {
    this.element.style.marginTop  = '-' + (this.element.offsetHeight / 2) + 'px';
    this.element.style.marginLeft = '-' + (this.element.offsetWidth / 2) + 'px';
  },
  
  onLoadPhoto: function() {
    this.unassignClass('busy');
  }
});

Component.create('overlay', {

  onClickElement: function(event) {
    this.hide();
  },
  
  addDialog: function(dialog) {
    document.body.appendChild(dialog.element);
    dialog.show();
    dialog.overlay = this;
    this.dialog = dialog;
  },
  
  open: function(url) {
    this.request('GET', url);    
    this.assignWithClass('overlayed', document.documentElement);
    
    var effect = new Fx.Opacity(this.element, { duration: 200 });
    
    effect.setStyle(this.element, 'opacity', 0);
    effect.custom(0, 0.6);
  },
  
  hide: function() {
    if (this.dialog) this.dialog.remove();
    
    var o = this;
    new Fx.Opacity(this.element, { duration: 200, onComplete: function() { o.unassignClass('overlayed') } }).custom(0.6, 0);    
  }
});

Component.create('popup', {

  onClickElement: function(event) {
    this.root.overlay.open(this.element.href);
  }
});

Component.create('addToFavourites', {

  onClickElement: function(event) {
    try          { window.external.AddFavorite(this.element.href, this.element.title); }
    catch(error) {}
  }
});
