var IE = /MSIE/.test(navigator.userAgent);

var Collection = {
  Container: Responder.create('.collection'),
  Item:      Responder.create('.item')
};

Object.extend(Collection.Container.prototype, {
  initialize: function(container) {
    this.container = container;
    this.create    = $A(document.getElementsByClassName('create')).detect(function(element) {
      return element.hasCommonClassName(container);
    });

    if (this.create) {
      if (Node.element(this.create, 'a')) {
        this.hijackLink('create');
      } else if (Node.element(this.create, 'form')) {
        this.hijackForm('create');
      }
      this.observe('create');
/*      if (container.hasClassName('sortable')) {
        //container.style.position = 'relative';
        Sortable.create(container, { tag: Collection.Tags[container.tagName.toLowerCase()], handle: 'move' });
      }*/
    }
  },
  
  onCreateSuccess: function(fragment) {
    var element = Element.first(fragment);
    
    if (element) {
      this.container.appendChild(element);
      element.hide();
      new Effect.Appear(element, { duration: 0.3, to: 0.999 });
      if (IE) Event.dispatch({ type: 'DOMNodeInserted', target: element });
      //Responder.initializeFor(element);
    }
  }
});

Object.extend(Collection.Item.prototype, {
  initialize: function(container) {
    this.container = container;
    this.destroy   = $A(container.getElementsByClassName('destroy')).detect(function(element) {
      return element.hasCommonClassName(container);
    });
    this.observe('destroy');
  },
    
  onClickDestroy: function(event) {
    Event.stop(event);
    if (!this.destroyed && (!this.destroy.innerHTML.match(/[A-Za-z]/) || confirm(this.destroy.innerHTML + '?'))) {
      this.destroyed = true;
      new Ajax.Request(this.destroy.href, { onSuccess: this.onDestroySuccess.bind(this) });
    }
  },
  
  onDestroySuccess: function(response) {
    new Effect.Fade(this.container, { duration: 0.4, afterFinish: function() {
      this.container.remove();
      if (IE) Event.dispatch({ type: 'DOMNodeRemoved', target: this.container });
    }.bind(this) });
  }
});

/*--------------------------------------------------------------------------*/

var ValueEditor = Responder.create('.editable'); // .value_editor
Object.extend(ValueEditor.prototype, {
  initialize: function(container) {
    this.assignElementsByClassName(container);
    this.container = container;
    
    if (container.className.indexOf('html') > -1
      && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
      this.replaceFieldWithHTMLEditor();
    }
    this.observe('value', 'cancel', 'save');
  },
  
  assignElementsByClassName: function(container) {
    var element, elements = container.getElementsByTagName('*');
    for (var i = 0; i < elements.length; i++) {
      element = elements[i];
      if (element.className.indexOf('field') > -1) {
        this.field = element;
      } else if (element.className) {
        this[element.className] = element;
      }
    }
  },
  
  onClickValue: function(event) {
    this.savedValue = this.getEditorValue();
    this.container.addClassName('editing');
  },

  onClickCancel: function(event) {
    Event.stop(event);
    this.setEditorValue(this.savedValue);
    this.container.removeClassName('editing');
  },
  
  onClickSave: function(event) {
    Event.stop(event);
    
    this.value.innerHTML = 'Saving...';
    this.container.removeClassName('editing');
    this.container.addClassName('saving');
    
    if (this.field.form.target) {
      Form.submitToIFrame(this.field.form, function(text) {
        this.container.removeClassName('saving');
        this.value.innerHTML = text;
      }.bind(this));
    } else { try {
      new Ajax.Request(this.field.form.action, { parameters: this.serialize(), onSuccess: function(response) {
        this.container.removeClassName('saving');
        this.value.innerHTML = response.responseText;
      }.bind(this)}); } catch(e) { alert(e) }
    }
  },
  
  replaceFieldWithHTMLEditor: function() {
    if (this.field) {
      Object.extend(new FCKeditor(this.field.name), HTMLEditor.Options).ReplaceTextarea();
      Object.extend(this, HTMLEditor.Methods);      
    }
  },
  
  serialize: function() {
    var object = {};
    object[this.field.name] = this.getEditorValue();
    return Hash.toQueryString(object);
  },
  
  getEditorValue: function() {
    return this.field.value;
  },
  
  setEditorValue: function(text) {
    this.field.value = text;
  }
});

var HTMLEditor = {
  Options: {
    BasePath: '/javascripts/fckeditor/',
    ToolbarSet: 'Basic',
    EditorAreaCSS: '/stylesheets/topyacht.css'
  },

  Methods: {    
    getEditorValue: function() {
      return this.contentDocument().body.innerHTML;
    },

    setEditorValue: function(text) {
      this.contentDocument().body.innerHTML = text;
    },
    
    contentDocument: function() {
      this.iframe           = $(this.field.name + '___Frame');
      this._contentDocument = this.document(this.document(this.iframe).body.getElementsByTagName('iframe')[0]);
      return this._contentDocument;
    },
    
    document: function(iframe) {
      return iframe.contentDocument || iframe.contentWindow.document;
    }
  }
};


/*--------------------------------------------------------------------------*/

var Slides = {
  next: function(item) {
    return $(item).next('li') || $(item.parentNode).down('li');
  },
  
  previous: function(item) {
    return $(item).previous('li') || $A(item.parentNode.getElementsByTagName('li')).last();    
  }
};


var Slide = Responder.create();
Object.extend(Slide.prototype, {
  
  initialize: function(element, slideShow) {
    this.container = element;
    this.slideShow = slideShow;

    Event.observe(element, 'DOMNodeRemoved', this.onRemoveContainer.bind(this));
  },

  onRemoveContainer: function(event) {
    if (this.container == event.target && this.container == this.slideShow.current) {
      this.slideShow.forward();
    }
  }
});

var Slidyshow = Responder.create('ul.slideshow');

Object.extend(Slidyshow.prototype, {
  initialize: function(container) {
    ['next', 'previous'].each(function(name) { // fixme: this is sloooow and shouldn't happen when not editing
      this[name] = Element.range(container).detect(function(element) {
        element = $(element);
        return element.hasClassName(name) && element.hasCommonClassName(container);
      }.bind(this));
    }.bind(this));
    
    $A(container.getElementsByTagName('li')).each(function(element) {
      new Slide(element, this);
    }.bind(this));
    
    this.container = container;
    this.show(container.down('li'));
    this.registerCallbacks();
  },
  
  registerCallbacks: function() {
    if (!this.next) {
      this.executer = new PeriodicalExecuter(this.forward.bind(this), 8);
    }
    
    Event.observe(this.container, 'DOMNodeInserted', this.onInsert.bind(this));
    this.observe('next', 'previous', 'container');
  },
  
  onInsert: function(event) {
    var node = event.target;
    if (Node.element(node, 'li') && node.parentNode == this.container) {
      new Slide(this.show(node), this);
    }
  },
  
  onClickNext: function() {
    this.forward();
  },

  onClickPrevious: function() {
    this.back();
  },

  back: function() {
    this.show(Slides.previous(this.current));
  },

  forward: function() {
    this.show(Slides.next(this.current));
  },
  
  show: function(item) {
    if (!item) return;
    if (this.current) this.current.hide();
    return this.current = item.show();
  }
});