import { mat3, mat4 } from 'gl-matrix';

import macro       from 'vtk.js/Sources/macro';
import vtkViewNode from 'vtk.js/Sources/Rendering/SceneGraph/ViewNode';

// ----------------------------------------------------------------------------
// vtkOpenGLImageSlice methods
// ----------------------------------------------------------------------------

function vtkOpenGLImageSlice(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkOpenGLImageSlice');

  // Builds myself.
  publicAPI.buildPass = (prepass) => {
    if (!model.renderable || !model.renderable.getVisibility()) {
      return;
    }
    if (prepass) {
      if (!model.renderable) {
        return;
      }

      publicAPI.prepareNodes();
      publicAPI.addMissingNode(model.renderable.getMapper());
      publicAPI.removeUnusedNodes();
    }
  };

   // we draw textures, then mapper, then post pass textures
  publicAPI.traverseOpaquePass = (renderPass) => {
    if (!model.renderable ||
        !model.renderable.getVisibility() ||
        !model.renderable.getIsOpaque()) {
      return;
    }

    publicAPI.apply(renderPass, true);
    model.children.forEach((child) => {
      child.traverse(renderPass);
    });
    publicAPI.apply(renderPass, false);
  };

  // we draw textures, then mapper, then post pass textures
  publicAPI.traverseTranslucentPass = (renderPass) => {
    if (!model.renderable ||
        !model.renderable.getVisibility() ||
        model.renderable.getIsOpaque()) {
      return;
    }

    publicAPI.apply(renderPass, true);
    model.children.forEach((child) => {
      child.traverse(renderPass);
    });
    publicAPI.apply(renderPass, false);
  };

  // Renders myself
  publicAPI.opaquePass = (prepass, renderPass) => {
    if (prepass) {
      model.context = publicAPI.getFirstAncestorOfType('vtkOpenGLRenderWindow').getContext();
      model.context.depthMask(true);
    }
  };

  // Renders myself
  publicAPI.translucentPass = (prepass, renderPass) => {
    if (prepass) {
      model.context = publicAPI.getFirstAncestorOfType('vtkOpenGLRenderWindow').getContext();
      model.context.depthMask(false);
    } else {
      model.context.depthMask(true);
    }
  };

  publicAPI.getKeyMatrices = () => {
    // has the actor changed?
    if (model.renderable.getMTime() > model.keyMatrixTime.getMTime()) {
      model.renderable.computeMatrix();
      mat4.copy(model.MCWCMatrix, model.renderable.getMatrix());
      mat4.transpose(model.MCWCMatrix, model.MCWCMatrix);

      if (model.renderable.getIsIdentity()) {
        mat3.identity(model.normalMatrix);
      } else {
        mat3.fromMat4(model.normalMatrix, model.MCWCMatrix);
        mat3.invert(model.normalMatrix, model.normalMatrix);
      }
      model.keyMatrixTime.modified();
    }

    return { mcwc: model.MCWCMatrix, normalMatrix: model.normalMatrix };
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  context: null,
  keyMatrixTime: null,
  normalMatrix: null,
  MCWCMatrix: null,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  // Inheritance
  vtkViewNode.extend(publicAPI, model, initialValues);

  model.keyMatrixTime = {};
  macro.obj(model.keyMatrixTime);
  model.normalMatrix = mat3.create();
  model.MCWCMatrix = mat4.create();

  // Build VTK API
  macro.setGet(publicAPI, model, [
    'context',
  ]);

  // Object methods
  vtkOpenGLImageSlice(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkOpenGLImageSlice');

// ----------------------------------------------------------------------------

export default { newInstance, extend };

@@ -836,16 +836,125 @@
 %0A  %7D;%0A%0A 
+ publicAPI.traverseOpaqueZBufferPass = (renderPass) =%3E %7B%0A    publicAPI.traverseOpaquePass(renderPass);%0A  %7D;%0A%0A
   // we 
@@ -1777,24 +1777,477 @@
 lse);%0A  %7D;%0A%0A
+  publicAPI.queryPass = (prepass, renderPass) =%3E %7B%0A    if (prepass) %7B%0A      if (!model.renderable %7C%7C%0A          !model.renderable.getVisibility()) %7B%0A        return;%0A      %7D%0A      if (model.renderable.getIsOpaque()) %7B%0A        renderPass.incrementOpaqueActorCount();%0A      %7D else %7B%0A        renderPass.incrementTranslucentActorCount();%0A      %7D%0A    %7D%0A  %7D;%0A%0A  publicAPI.opaqueZBufferPass = (prepass, renderPass) =%3E publicAPI.opaquePass(prepass, renderPass);%0A%0A
   // Renders

fix issue with image mapper