var OperatorOrder = new Class({

  Implements: Options,

  initialize: function(el, data, options) {
    this.el = $(el);
    this.setOptions(options);
    var selects = [ 'materiale', 'modello', 'misuraL', 'misuraD' ].map(function(name) {
      return this.el.getElement('select[name=' + name + ']');
    }, this);
    this.dynSel = new DynSelect(data, selects);
    this.numeroFori = this.el.getElement('select[name=numeroFori]');
    this.tipoForatura = this.el.getElement('select[name=tipoForatura]');
    this.quantity = this.el.getElement('input[name=quantity]');
    this.note = this.el.getElement('textarea[name=note]');
    this.add = this.el.getElement('.add').addEvent('click', this.handleAdd.bindWithEvent(this));
    this.update = this.el.getElement('.update').addEvent('click', this.handleUpdate.bindWithEvent(this));
    this.cancel = this.el.getElement('.cancel').addEvent('click', this.handleCancel.bindWithEvent(this));
    this.lines = this.el.getElement('.lines');
    this.emptyOrder = this.lines.getElement('.empty');
    this.emptyOrder.set('text', this.options.emptyOrderMessage);
    this.hiddens = this.el.getElement('.hiddens');
    this.orderLines = [];
  },

  performValidation: function() {
    var valid = true;
    this.el.getElements('.required').each(function(el) {
      var v = el.get('value') != '';
      el[(v ? 'remove' : 'add') + 'Class']('error');
      valid = valid && v;
    }, this);
    return valid;
  },

  handleAdd: function(e) {
    e.stop();
    if (!this.performValidation()) return;
    var values = this.dynSel.getValues();
    var el = new Element('div').addClass('orderLine').set('html', 
      '<span class="materiale"></span>'
      + '<span class="modello"></span>'
      + '<span class="misuraL"></span>'
      + '<span class="x"> X </span>'
      + '<span class="misuraD"></span>'
      + '<span class="numeroFori"></span>'
      + '<span class="tipoForatura"></span>'
      + '<span class="numeroFori"></span>'
      + '<span class="tipoForatura"></span>'
      + '<span class="quantity"></span>'
      + '<span class="note"></span>'
      + '<span class="action"><a href="#" class="edit">' + this.options.editIcon + this.options.editAction + '</a>'
      + '<br/><a href="#" class="delete">' + this.options.deleteIcon + this.options.deleteAction + '</a></span>'
      + '<div class="clear"></div>');
    this.lines.adopt(el);
    this.orderLines.push(new OperatorOrder.Line(el)
      .setValues(this.getValues())
      .addEvent('edit', this.handleEdit.bind(this))
      .addEvent('delete', this.handleDelete.bind(this)));
    this.refreshLines();
    this.empty();
  },

  handleUpdate: function(e) {
    e.stop();
    if (!this.performValidation()) return;
    this.line.setValues(this.getValues());
    this.empty();
  },

  handleCancel: function(e) {
    e.stop();
    this.empty();
  },

  handleEdit: function(line) {
    this.line = line;
    this.setValues(this.line.getValues());
    this.add.setStyle('display', 'none');
    this.update.setStyle('display', '');
    this.cancel.setStyle('display', '');
  },

  handleDelete: function(line) {
    if (confirm(this.options.confirmDeleteMessage)) {
      if (this.line == line) this.empty();
      line.removeEvents('edit').removeEvents('delete').el.dispose();
      this.orderLines.erase(line);
      this.refreshLines();
    }
  },

  getValues: function() {
    return this.dynSel.getValues().concat([ this.numeroFori.get('value'), this.tipoForatura.get('value'), this.quantity.get('value'), this.note.get('value') ]);
  },

  setValues: function(values) {
    this.dynSel.setValues(values);
    $A(this.numeroFori.options).filter(function(opt) { return opt.value == values[4]; }).each(function(opt) { opt.selected = true; });
    $A(this.tipoForatura.options).filter(function(opt) { return opt.value == values[5]; }).each(function(opt) { opt.selected = true; });
    this.quantity.set('value', values[6]);
    this.note.set('value', values[7]);
  },

  empty: function() {
    this.setValues([ '', '', '', '', '', '', '', '' ]);
    this.update.setStyle('display', 'none');
    this.cancel.setStyle('display', 'none');
    this.add.setStyle('display', '');
    this.line = null;
  },

  populateHiddens: function() {
    this.hiddens.empty().adopt(new Element('input', { type: 'hidden', name: 'orderSize', value: this.orderLines.length }));
    this.orderLines.each(function(line, i) {
      var values = line.getValues();
      OperatorOrder.Line.fields.each(function(f, j) {
        this.hiddens.adopt(new Element('input', { type: 'hidden', name: f + '_' + i, value: values[j] }));
      }, this);
    }, this);
  },

  refreshLines: function() {
    this.emptyOrder.setStyle('display', this.orderLines.length == 0 ? '' : 'none');
    this.orderLines.each(function(line, i) {
      line.el[(i % 2 ? 'add' : 'remove') + 'Class']('even');
    });
  }

});

OperatorOrder.Line = new Class({

  Implements: Events,

  initialize: function(el) {
    this.el = $(el);
    this.el.getElement('.edit').addEvent('click', this.handleEdit.bindWithEvent(this));
    this.el.getElement('.delete').addEvent('click', this.handleDelete.bindWithEvent(this));
  },

  handleEdit: function(e) {
    e.stop();
    this.fireEvent('edit', this);
  },

  handleDelete: function(e) {
    e.stop();
    this.fireEvent('delete', this);
  },

  getValues: function() {
    return OperatorOrder.Line.fields.map(function(f) {
      return this.el.getElement('.' + f).get('text');
    }, this);
  },

  setValues: function(values) {
    OperatorOrder.Line.fields.each(function(f, index) {
      this.el.getElement('.' + f).set('text', values[index]);
    }, this);
    return this;
  }

});

OperatorOrder.Line.fields = [ 'materiale', 'modello', 'misuraL', 'misuraD', 'numeroFori', 'tipoForatura', 'quantity', 'note' ];
