/**
 * Copyright (c) Artenum SARL 2004-2005
 * @author Sebastien Jourdain
 *
 * All rights reserved. This software can
 * not be used or copy or diffused without
 * an explicit license of Artenum SARL, Paris-France
 */
package com.artenum.cassandra.ui;

import vtk.vtkActor;
import vtk.vtkAssembly;
import vtk.vtkAxes;
import vtk.vtkConeSource;
import vtk.vtkPolyDataMapper;
import vtk.vtkTextActor;
import vtk.vtkTubeFilter;

import com.artenum.cassandra.pipeline.SimplePipeLineManager;

/**
 * @author seb
 */
public class DefaultAxes {
    private final double axisLength = 0.8;
    private final SimplePipeLineManager pipelineManager;
    private final vtkTextActor xactor;
    private final vtkTextActor yactor;
    private final vtkTextActor zactor;
    private final vtkConeSource xcone;
    private final vtkConeSource ycone;
    private final vtkConeSource zcone;
    private final vtkAssembly assembly;

    public DefaultAxes(final SimplePipeLineManager pipelineManager) {
        this.pipelineManager = pipelineManager;
        final vtkAxes axes = new vtkAxes();
        axes.SetOrigin(0, 0, 0);
        axes.SetScaleFactor(this.axisLength);

        this.xactor = new vtkTextActor();
        this.yactor = new vtkTextActor();
        this.zactor = new vtkTextActor();

        this.xactor.SetInput("X");
        this.yactor.SetInput("Y");
        this.zactor.SetInput("Z");

        this.xactor.SetTextScaleMode(1);
        this.yactor.SetTextScaleMode(1);
        this.zactor.SetTextScaleMode(1);

        this.xactor.GetPositionCoordinate().SetCoordinateSystemToWorld();
        this.yactor.GetPositionCoordinate().SetCoordinateSystemToWorld();
        this.zactor.GetPositionCoordinate().SetCoordinateSystemToWorld();

        this.xactor.GetPositionCoordinate().SetValue(this.axisLength, 0.0, 0.0);
        this.yactor.GetPositionCoordinate().SetValue(0.0, this.axisLength, 0.0);
        this.zactor.GetPositionCoordinate().SetValue(0.0, 0.0, this.axisLength);

        this.xactor.GetTextProperty().SetColor(1.0, 1.0, 1.0);
        this.xactor.GetTextProperty().ShadowOn();
        this.xactor.GetTextProperty().ItalicOn();
        this.xactor.GetTextProperty().BoldOff();

        this.yactor.GetTextProperty().SetColor(1.0, 1.0, 1.0);
        this.yactor.GetTextProperty().ShadowOn();
        this.yactor.GetTextProperty().ItalicOn();
        this.yactor.GetTextProperty().BoldOff();

        this.zactor.GetTextProperty().SetColor(1.0, 1.0, 1.0);
        this.zactor.GetTextProperty().ShadowOn();
        this.zactor.GetTextProperty().ItalicOn();
        this.zactor.GetTextProperty().BoldOff();

        this.xactor.SetMaximumLineHeight(0.25);
        this.yactor.SetMaximumLineHeight(0.25);
        this.zactor.SetMaximumLineHeight(0.25);

        final vtkTubeFilter tube = new vtkTubeFilter();
        tube.SetInput(axes.GetOutput());
        tube.SetRadius(0.05);
        tube.SetNumberOfSides(8);

        final vtkPolyDataMapper tubeMapper = new vtkPolyDataMapper();
        tubeMapper.SetInput(tube.GetOutput());

        final vtkActor tubeActor = new vtkActor();
        tubeActor.SetMapper(tubeMapper);
        tubeActor.PickableOff();

        final int coneRes = 12;
        final double coneScale = 0.3;

        // --- x-Cone
        this.xcone = new vtkConeSource();
        this.xcone.SetResolution(coneRes);
        final vtkPolyDataMapper xconeMapper = new vtkPolyDataMapper();
        xconeMapper.SetInput(this.xcone.GetOutput());
        final vtkActor xconeActor = new vtkActor();
        xconeActor.SetMapper(xconeMapper);
        xconeActor.GetProperty().SetColor(1, 0, 0);
        xconeActor.SetScale(coneScale, coneScale, coneScale);
        xconeActor.SetPosition(this.axisLength, 0.0, 0.0);

        // --- y-Cone
        this.ycone = new vtkConeSource();
        this.ycone.SetResolution(coneRes);
        final vtkPolyDataMapper yconeMapper = new vtkPolyDataMapper();
        yconeMapper.SetInput(this.ycone.GetOutput());
        final vtkActor yconeActor = new vtkActor();
        yconeActor.SetMapper(yconeMapper);
        yconeActor.GetProperty().SetColor(1, 1, 0);
        yconeActor.RotateZ(90);
        yconeActor.SetScale(coneScale, coneScale, coneScale);
        yconeActor.SetPosition(0.0, this.axisLength, 0.0);

        // --- z-Cone
        this.zcone = new vtkConeSource();
        this.zcone.SetResolution(coneRes);
        final vtkPolyDataMapper zconeMapper = new vtkPolyDataMapper();
        zconeMapper.SetInput(this.zcone.GetOutput());
        final vtkActor zconeActor = new vtkActor();
        zconeActor.SetMapper(zconeMapper);
        zconeActor.GetProperty().SetColor(0, 1, 0);
        zconeActor.RotateY(-90);
        zconeActor.SetScale(coneScale, coneScale, coneScale);
        zconeActor.SetPosition(0.0, 0.0, this.axisLength);

        //
        this.assembly = new vtkAssembly();
        this.assembly.AddPart(tubeActor);
        this.assembly.AddPart(xconeActor);
        this.assembly.AddPart(yconeActor);
        this.assembly.AddPart(zconeActor);
    }

    public void setVisible(final boolean view) {
        if (view) {
            this.pipelineManager.getCassandraView().GetRenderer().AddActor2D(this.xactor);
            this.pipelineManager.getCassandraView().GetRenderer().AddActor2D(this.yactor);
            this.pipelineManager.getCassandraView().GetRenderer().AddActor2D(this.zactor);
            this.pipelineManager.getCassandraView().GetRenderer().AddActor(this.assembly);
        } else {
            this.pipelineManager.getCassandraView().GetRenderer().RemoveActor2D(this.xactor);
            this.pipelineManager.getCassandraView().GetRenderer().RemoveActor2D(this.yactor);
            this.pipelineManager.getCassandraView().GetRenderer().RemoveActor2D(this.zactor);
            this.pipelineManager.getCassandraView().GetRenderer().RemoveActor(this.assembly);
        }
    }
}
