import ons from 'onsenui';
import {Container, inject} from 'aurelia-dependency-injection';
import {createOverrideContext} from 'aurelia-binding';
import {ViewSlot, ViewLocator, customElement, noView, BehaviorInstruction, bindable, CompositionTransaction, CompositionEngine, ShadowDOM, SwapStrategies} from 'aurelia-templating';
import {Router} from 'aurelia-router';
import {Origin} from 'aurelia-metadata';
import {DOM} from 'aurelia-pal';
import {RouterView} from 'aurelia-templating-router';
import {RouterViewLocator} from 'aurelia-templating-router/router-view';
import {invokeLifecycle} from './lifecycle';

@customElement('ons-navigator')
@noView
@inject(DOM.Element, Container, ViewSlot, Router, ViewLocator, CompositionTransaction, CompositionEngine)
export class OnsNavigator extends RouterView {
  @bindable swapOrder;
  @bindable layoutView;
  @bindable layoutViewModel;
  @bindable layoutModel;
  element;

  constructor(element, container, viewSlot, router, viewLocator, compositionTransaction, compositionEngine) {
    super(element, container, viewSlot, router, viewLocator, compositionTransaction, compositionEngine);

    this.element.pageLoader = new ons.PageLoader(this.load.bind(this), this.unload.bind(this));

    this.view;
    this.viewStack = [];
  }

  swap(viewPortInstruction) {
    let options = {
      data: viewPortInstruction
    }
    let router = this.router;
    if (router.isNavigatingBack) {
      return this.element.popPage(options);
    } else {
      return this.element.pushPage(viewPortInstruction.moduleId, options);
    }
  }

  load({page, parent, params}, done) {
    let viewPortInstruction = params;
    let previousView = this.view;

    let work = () => {
      let pageElement = this.view.fragment.firstElementChild;
      this.viewSlot.add(this.view);
      if (previousView) {
        this.viewStack.push(previousView);
      }
      this._notify();
      return done(pageElement);
    };

    let ready = owningView => {
      viewPortInstruction.controller.automate(this.overrideContext, owningView);
      if (this.compositionTransactionOwnershipToken) {
        return this.compositionTransactionOwnershipToken.waitForCompositionComplete().then(() => {
          this.compositionTransactionOwnershipToken = null;
          return work();
        });
      }

      return work();
    };

    this.view = viewPortInstruction.controller.view;

    return ready(this.owningView);
  }

  unload(pageElement) {
    return invokeLifecycle(this.view.controller.viewModel, 'deactivate').then(() => {
      this.viewSlot.remove(this.view);
      this.view.unbind();
      this.view = this.viewStack.pop();
    });
  }
}

@@ -1313,179 +1313,383 @@
 let 
-options = %7B%0A      data: viewPortInstruction%0A    %7D%0A    let router = this.router;%0A    if (router.isNavigatingBack) %7B%0A      return this.element.popPage(options);%0A    %7D else %7B
+router = this.router;%0A    if (router.isNavigatingBack) %7B%0A      let options = router.currentInstruction.previousInstruction.config.settings.navigator %7C%7C %7B%7D;%0A      options.data = viewPortInstruction;%0A      return this.element.popPage(options);%0A    %7D else %7B%0A      let options = router.currentInstruction.config.settings.navigator %7C%7C %7B%7D;%0A      options.data = viewPortInstruction;
 %0A   

add navigation transitions