smilemaker = window.smilemaker || {};
smilemaker.importer = smilemaker.importer || {}

smilemaker.importer.ImporterApp = function()
{
  // create controllers
  var controllers = $A([]);
  $$('.js-workflow-view').each(function(v)
    {
      controllers.push( new smilemaker.importer.WorkflowController(v, false) );
    });
  this.controllers = controllers;

  this.workflowContainer = $$('.js-workflow-container')[0];
  this.addWorkflowButton = $$('.js-add-workflow')[0];
  this.addWorkflowButton.observe('click',this.addWorkflow.bindAsEventListener(this));

  document.observe("import:delete", this.handleDeleteEvent.bind(this));
  document.observe("import:update", this.handleUpdateEvent.bind(this));
  document.observe("import:editing", this.toggleOthersOff.curry('editing','cancelEdit').bind(this));
  document.observe("import:view", this.toggleOthersOff.curry('viewing','hideDetails').bind(this));
  document.observe("import:start", this.toggleOthersOff.curry('started','unstart').bind(this));

  this.addController = null;
}
smilemaker.importer.ImporterApp.prototype = {
  addWorkflow : function()
  {
    if ( this.addController )
      return;

    new Ajax.Request( this.addWorkflowButton.href, { method:'get', onSuccess:this.insertAddUI.bind(this) });
  },

  insertAddUI : function( addUI )
  {
    this.workflowContainer.insert( {bottom:addUI.responseText.strip()} );
    this.addController = new smilemaker.importer.WorkflowController( $(this.workflowContainer.lastChild), true );
    this.controllers.add( this.addController );
  },

  handleDeleteEvent : function( event )
  {
    if ( event.memo.controller === this.addController )
      this.addController = null;

    this.controllers.slice( this.controllers.indexOf(event.memo.controller), 1 );
  },

  handleUpdateEvent : function( event )
  {
    if ( event.memo.controller === this.addController )
      this.addController = null;
  },

  toggleOthersOff : function(testProp, f, event)
  {
    this.controllers.each( function(c)
      {
        if (( c[testProp] ) && ( event.memo.controller !== c ))
          c[f]();
      });
  }
}

smilemaker.importer.WorkflowController = function( view, isAdding )
{
  this.view = view;
  this.isAdding = isAdding;
  this.viewing = false;
  this.editing = false;
  this.started = false;
  if ( this.isAdding )
    this.wireForEditing( view );
  else
    this.wireForViewing( view );
}
smilemaker.importer.WorkflowController.prototype = {
  edit : function()
  {
    if ( this.editing )
      return;

    this.hideDetails();
    new Ajax.Request( this.editButton.href, { method:'get', onSuccess:this.swapEditUI.bind(this) });
    this.editing = true;
  },

  deleteWorkflow : function()
  {
    if ( this.editing )
      return;

    new Ajax.Request( this.deleteButton.href, { method:'post', onSuccess:this.workflowDeleted.bind(this) });
    this.editing = true;
  },

  wireForViewing : function( view )
  {
    this.startButton = view.select('.js-start-button')[0];
    this.startButton.observe('click', this.start.bind(this) );

    this.importForm = view.select('.js-import-form')[0];
    this.importForm.hide();
    this.formController = new smilemaker.importer.ImportFormController( this.importForm );

    this.detailView = view.select('.js-detail-view')[0];
    this.detailView.hide();

    this.editButton = view.select('.js-edit-button')[0];
    this.editButton.observe('click', this.edit.bind(this) );

    this.deleteButton = view.select('.js-delete-button')[0];
    this.deleteButton.observe('click', this.deleteWorkflow.bind(this) );

    this.viewDetailsButton = view.select('.js-view-details')[0];
    this.viewDetailsButton.observe('click', this.viewDetails.bind(this) );

    view.select('.js-hide-details')[0].observe('click', this.hideDetails.bind(this) );
    view.select('.js-cancel-button')[0].observe('click', this.unstart.bind(this) );

    this.editing = false;
  },

  start : function()
  {
    this.importForm.show();
    this.startButton.hide();
    this.started = true;
    document.fire("import:start", {controller:this} );
  },

  unstart : function()
  {
    this.startButton.show();
    this.started = false;
    this.importForm.hide();
  },

  viewDetails : function()
  {
    this.detailView.show();
    this.viewDetailsButton.hide();
    this.viewing = true;
    document.fire("import:view", {controller:this} );
  },

  hideDetails : function()
  {
    this.detailView.hide();
    this.viewDetailsButton.show();
    this.viewing = false;
  },

  wireForEditing : function( view )
  {
    this.editForm = view.select('.js-edit-form')[0];
    view.select('.js-update-button')[0].observe('click', this.update.bindAsEventListener(this) );
    view.select('.js-cancel-button')[0].observe('click', this.cancelEdit.bindAsEventListener(this) );

    this.scheduleInput = view.select('.js-schedule')[0];
    this.inputURLInput = view.select('.js-input-url')[0];
    this.automateCheck = view.select('.js-automate')[0];
    this.automateCheck.observe('click', this.toggleAutomation.bindAsEventListener(this) );
    this.scheduleInfo = view.select('.js-schedule-info');

    if (( this.scheduleInput.value == null ) || ( this.scheduleInput.value.length == 0 ))
    {
      this.scheduleInfo.each(function(si) { si.hide() });
    }
    else
    {
      this.scheduleInfo.each(function(si) { si.show() });
      this.automateCheck.checked = true;
    }

    this.view.select('.js-transform-select').each(function(s)
      {
        s.observe('change',this.updateTransformVisibility.bind(this));
      }.bind(this));
    this.updateTransformVisibility();

    this.editing = true;

    document.fire('import:editing', {controller:this} );
  },

  toggleAutomation : function()
  {
    if ( ! this.scheduleInfo[0].visible() )
    {
      if (( this.scheduleInput.value == null ) || ( this.scheduleInput.value.length == 0 ))
        this.scheduleInput.value = '0 0 1 ? * SUN';
      this.scheduleInfo.each(function(si) { si.show() });
    }
    else
    {
      this.scheduleInput.value = '';
      this.inputURLInput.value = '';
      this.scheduleInfo.each(function(si) { si.hide() });
    }
  },

  updateTransformVisibility : function()
  {
    var hide = false;
    this.view.select('.js-transform-editor').each(function(e)
      {
        if ( hide )
        {
          e.hide();
          return;
        }

        e.show();
        if ( ! $F(e.select('.js-transform-select')[0]) )
          hide = true;
      });
  },

  update : function()
  {
    new Ajax.Request( this.editForm.action,
    {
      method:     'post',
      parameters: this.editForm.serialize(true),
      onSuccess:  this.updateSuccessful.bind(this)
    })
  },

  workflowDeleted : function()
  {
    this.view.remove();
    document.fire('import:delete', {controller:this} )
  },

  cancelEdit : function()
  {
    this.view.remove();
    if ( this.isAdding )
    {
      document.fire('import:delete', {controller:this} )
      return;
    }

    this.view = this.oldView;
    this.editing = false;
    this.view.show();
  },

  updateSuccessful : function( viewUI )
  {
    this.swapViewUI( viewUI );
    this.isAdding = false;
    document.fire("import:update", {controller:this});
  },

  swapViewUI : function( viewUI )
  {
    if ( this.oldView )
      this.oldView.remove();
    this.view = this.replaceAndReturn( this.view, viewUI.responseText );
    this.wireForViewing( this.view );
  },

  swapEditUI : function( editUI )
  {
    this.lastRequest = editUI.request;

    this.view.insert( {after:editUI.responseText.strip()} );
    this.oldView = this.view;
    this.view = $(this.oldView.nextSibling);
    this.oldView.hide();
    this.wireForEditing( this.view );
  },

  replaceAndReturn : function( oldDom, newHTML )
  {
    var reference = null;
    if ( oldDom.previousSibling )
    {
      reference = oldDom.previousSibling;
      oldDom.replace( newHTML.strip() );
      return $(reference.nextSibling);
    }
    else
    {
      reference = oldDom.parentNode;
      oldDom.replace( newHTML.strip() );
      return $(reference.firstChild);
    }
  }
}

smilemaker.importer.ImportFormController = function( view )
{
  this.fileInput = view.select(".js-import-xml-input")[0];
  if ( this.fileInput )
    this.fileInput.observe('change', this.fileBrowsed.bind(this) );

  this.fakeFileInput = view.select(".js-import-xml-text")[0];

  var clear = view.select('.js-import-xml-clear')[0]
  if ( clear )
      clear.observe('click', this.fileCleared.bind(this) );

  this.form = view.select('.js-import-form')[0];
  this.testRun = view.select('.js-test-run')[0];

  this.previewButton = view.select('.js-preview-button')[0];
  this.previewButton.observe('click', this.runImportTest.bind(this) );

  this.importButton = view.select('.js-import-button')[0];
  this.importButton.observe('click', this.runImport.bind(this) );

  if ( this.fileInput )
    this.unsetFile();
}
smilemaker.importer.ImportFormController.prototype = {
  fileBrowsed : function()
  {
    if ( this.fileInput.value != "" )
      this.setFile();
    else
      this.unsetFile();
  },

  setFile : function()
  {
    this.fakeFileInput.value = this.fileInput.value;
    this.previewButton.disabled = false;
    this.previewButton.removeClassName('disabled');
    this.importButton.disabled = false;
    this.importButton.removeClassName('disabled');
  },

  unsetFile : function()
  {
    this.fakeFileInput.value = "Click Browse to choose a input XML file.";
    this.previewButton.disabled = true;
    this.previewButton.addClassName('disabled');
    this.importButton.disabled = true;
    this.importButton.addClassName('disabled');
  },

  fileCleared : function()
  {
    var newFileInput = this.fileInput.cloneNode(true);
    this.fileInput.replace( newFileInput );
    this.fileInput = newFileInput;
    this.fileInput.observe('change', this.fileBrowsed.bind(this) );
    this.unsetFile();
  },

  runImportTest : function()
  {
    this.testRun.value = true;
    this.form.submit();
  },

  runImport : function()
  {
    this.testRun.value = false;
    this.form.submit();
  }
}

function executeDelete( deleteURL, row )
{
  new Ajax.Request( deleteURL, {method:'get',onSuccess:function()
    {
      $(row).remove();
      var odd = true;
      $('stats-table').select('tr.js-stats-row').each(function(tr)
        {
          if ( odd )
            tr.addClassName('odd');
          else
            tr.removeClassName('odd');
          odd = ! odd;
        } );
    } });
}

document.observe("dom:loaded", function()
  {
    smilemaker.importer.app = new smilemaker.importer.ImporterApp();
  });

