'use strict';

var debug = require('debug')('diagram-tab');

var inherits = require('inherits');

var h = require('vdom/h');

var isUnsaved = require('util/file/is-unsaved'),
    ensureOpts = require('util/ensure-opts');

var Tab = require('base/components/tab');

var assign = require('lodash/object/assign'),
    find = require('lodash/collection/find');


/**
 * A tab displaying a diagram.
 *
 * @param {Object} options
 */
function DiagramTab(options, viewOptions) {

  ensureOpts([ 'events', 'file' ], options);

  Tab.call(this, options);

  this.views = this.createViews(options);

  this.activeView = this.views[0];

  this.showView = function(id, options) {

    var file = this.file,
        view = this.getView(id),
        oldView = this.activeView;

    options = options || {};

    // export xml
    this.activeView.saveXML((err, xml) => {
      if (err) {
        return;
      }

      if (file.contents !== xml) {
        file.contents = xml;
      }

      this.activeView = view;

      debug('show view %s', view.id);

      this.events.emit('changed');

      // import xml
      view.setXML(xml);

      view.once('imported', function(err, data) {
        if (err) {
          this.activeView = oldView;

          debug('show view %s', oldView.id);

          this.events.emit('changed');
          return;
        }

        this.events.emit('changed');
      });

    });
  };

  /**
   * Save the tab, calling back with (err, file).
   *
   * @param {Function} done
   *
   * @return {Object}
   */
  this.save = function(done) {
    if (this.activeView.save) {
      this.activeView.save(done);
    }
  };

  this.updateState = function(newState) {
    this.events.emit('tools:state-changed', this, newState);
  };

  this.triggerAction = function(action, options) {
    if (this.activeView.triggerAction) {
      this.activeView.triggerAction(action, options);
    }
  };

  this.setFile = function(file) {
    this.file = file;
    this.label = file.name,
    this.title = file.path,

    this.events.emit('changed');
  };

  this.getView = function(id) {
    var view;

    if (typeof id === 'string') {
      view = find(this.views, { id: this.id + '#' + id });
    } else {
      view = id;
    }

    if (!view) {
      throw new Error('no view ' + id);
    }

    return view;
  };

  this.isUnsaved = function() {
    return isUnsaved(this.file);
  };

  this.render = function() {

    var compose = this.compose;

    return (
      <div className="diagram-tab tabbed">
        <div className="content">
          { h(this.activeView) }
        </div>

        <div className="tabs">
          {
            this.views.map(view => {
              return (
                <div className={ 'tab ' + (this.activeView === view ? 'active' : '') }
                     tabIndex="0"
                     onClick={ compose('showView', view) }>
                  { view.label }
                </div>
              );
            })
          }
        </div>
      </div>
    );
  };

  // set file
  this.setFile(options.file);
}

inherits(DiagramTab, Tab);

module.exports = DiagramTab;


DiagramTab.prototype.createViews = function(options) {
  debug('create views', options.viewDefinitions);

  return options.viewDefinitions.map(definition => {
    var id = definition.id,
        opts = assign({}, options, {
          id: options.id + '#' + id,
          label: definition.label,
          tab: this,
          file: undefined
        });

    var ViewComponent = definition.component;

    return new ViewComponent(opts);
  });
};

@@ -480,16 +480,20 @@
 reOpts(%5B
+%0A   
  'events
@@ -498,15 +498,21 @@
 ts',
+%0A   
  'file'
+%0A 
  %5D, 
@@ -1589,20 +1589,24 @@
 iew.save
+XML
 ) %7B%0A
+%0A
       th
@@ -1627,130 +1627,167 @@
 save
-(done);%0A    %7D%0A  %7D;%0A%0A  this.updateState = function(newState) %7B%0A    this.events.emit('tools:state-changed', this, newState);
+XML((err, xml) =%3E %7B%0A%0A        if (err) %7B%0A          return done(err);%0A        %7D%0A%0A        return done(null, assign(this.file, %7B contents: xml %7D));%0A      %7D);%0A    %7D
 %0A  %7D
@@ -2060,16 +2060,60 @@
 .path,%0A%0A
+    this.activeView.setXML(file.contents);%0A%0A
     this
@@ -3509,56 +3509,8 @@
 abel
-,%0A          tab: this,%0A          file: undefined
 %0A   
@@ -3570,22 +3570,31 @@
 t;%0A%0A    
-return
+var component =
  new Vie
@@ -3610,16 +3610,214 @@
 t(opts);
+%0A%0A    component.on('layout:changed', this.events.composeEmitter('layout:update'));%0A%0A    component.on('state-updated', this.events.composeEmitter('tools:state-changed', this));%0A%0A    return component;
 %0A  %7D);%0A%7D

rewrite forward of diagram tab events