//
// This file is part of MorphoGraphX - http://www.MorphoGraphX.org
// Copyright (C) 2012-2015 Richard S. Smith and collaborators.
//
// If you use MorphoGraphX in your work, please cite:
//   http://dx.doi.org/10.7554/eLife.05864
//
// MorphoGraphX is free software, and is licensed under under the terms of the 
// GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
// 
#ifndef IMAGE_DATA_H
#define IMAGE_DATA_H

#include <Config.hpp>

#include <ClipRegion.hpp>
#include <ColorBar.hpp>
#include <Colors.hpp>
#include <ColorMap.hpp>
#include <Geometry.hpp>
#include <Mesh.hpp>
#include <MGXViewer/qglviewer.h>
#include <Misc.hpp>
#include <Parms.hpp>
#include <Process.hpp>
#include <ScaleBar.hpp>
#include <Shader.hpp>
#include <TransferFunction.hpp>
#include <ColorEditDlg.hpp>
#include <GraphUtils.hpp>
#include <string>
#include <string.h>

#include <CImg.h>


namespace mgx 
{
  class CutSurf;
  class TransferFunctionDlg;
  
  typedef Vector<4, vertex> Point4v;
  typedef Vector<3, GLubyte> Point3GLub;
  
  class mgx_EXPORT ImgData : public QObject
  {
    Q_OBJECT
  public:
    static const uint RELOAD_NONE = 0x0;
    static const uint RELOAD_MAIN = 0x1;
    static const uint RELOAD_WORK = 0x2;
    static const uint RELOAD_TRIS = 0x4;
    static const uint RELOAD_LINES = 0x8;
    static const uint RELOAD_POS = 0x10;
    static const uint RELOAD_VBO = 0x20;
    static const uint UPDATE_SELECTION = 0x40;
  
    int StackId;
  
    Stack* stack;
    Mesh* mesh;
  
    // Main and stack paramters
    bool Main16Bit, Work16Bit;

    // General
    ColorEditDlg *triangleColorEditDlg;
    TransferFunctionDlg* workTransferDlg, *mainTransferDlg, *surfTransferDlg, *heatTransferDlg;
    // Function defining the color of the pixels
    std::vector<TransferFunction::Colorf> MainColorMap;   // Color map for the main data
    std::vector<TransferFunction::Colorf> WorkColorMap;   // Color map for the work data
    std::vector<TransferFunction::Colorf> SurfColorMap;   // Color map for the surface
    std::vector<TransferFunction::Colorf> HeatColorMap;   // Color map for the heatmap
    // If true, a new texture need to be sent for the colormap
    bool newMainColorMap, newWorkColorMap, newSurfColorMap, newHeatColorMap;
    std::vector<double> MainHist;   // Histogram of the main data
    std::vector<double> WorkHist;   // Histogram of the working data
    std::vector<double> SurfHist;   // Histogram of the surface data
    std::vector<double> HeatHist;   // Histogram of the surface data
    std::pair<double, double> mainBounds;
    std::pair<double, double> workBounds;

    GLuint mainDataTexId;              // 3D texture Id for main stack
    GLuint workDataTexId;              // 3D texture Id for work stack
    GLuint dataTexColor;               // 3D texture color
    GLuint surfTexId;                  // 1D texture map for surface colors.
    GLuint heatTexId;                  // 1D texture map for heatmap colors.
    GLuint colorMapTexId;              // 1D texture map for colormaps
    GLuint imgTexId;                   // 2D texture map for surface from an image
    GLuint mcmapTexId, wcmapTexId;     // 1D texture map for volume colors.
    GLuint labelTexId;                 // 1D texture map to color indexed texture for labels
    vertex_identity_t lineId;          // Last id when drawing lines
    VtxVec selectV;                    // List of selected vertices

    GLuint selFboId;                   // ID of selection buffer;
    GLuint selFboColor;                // Texture for colors
    GLuint selFboDepth;                // Texture for depth
  
    Colors::ColorType MeshColor;
    Colors::ColorType MeshBorderColor;
    // Colors::ColorType MeshPointColor;
    Colors::ColorType MeshSelectColor;
  
    // Helper arrays for vertex buffer obejects
    std::vector<vertex> idVA;  // Vertex ids
    std::vector<cell> triCell; // Cell list to go with triangles for 3D cells
  
    // VBO arrays
    std::vector<Point3f> posVA;      // Vertex positions
    std::vector<Point3f> nrmlVA;     // Vertex normals
    std::vector<Point3GLub> selVA;   // Unique colors for triangle selection
    std::vector<Point3f> texVA;      // Mesh labels, signal, and heat
    std::vector<Point2f> imgVA;      // Image texture coordinates
    std::vector<Colorb> triangleColorVA;
    std::vector<Colorb> cellColorVA;  // Array for cell colors
  
    std::vector<Point3f> pntsVA;         // Vertices for drawing points
    std::vector<Point3GLub> pcolVA;      // Colors for points
    std::vector<uint> pbrdVA;            // Indices for drawing border points
    std::vector<uint> pcellVA;           // Indices for drawing cell border points
    std::vector<uint> pselVA;            // Indices for drawing selected points  

    std::vector<uint> lineVA;    // Indices for drawing lines
    std::vector<uint> lbrdVA;    // Indices for drawing border lines
    std::vector<uint> lcellVA;   // Indices for drawing cell border lines
    std::vector<uint> lselVA;    // Indices for drawing selected lines

    std::vector<Point3f> cellGraphPosVA;  // Cell graph centers
    std::vector<Point3GLub> cellGraphColorVA;  // Cell Graph colors for centers
    std::vector<uint> cellGraphPointVA;   // Indices for drawing cell centers
    std::vector<uint> cellGraphLineVA;  // Indices for drawing lines that connect cell centers

    std::vector<Point3f> axisPosVA;
    std::vector<Point3GLub> axisColorVA;
  
    GLuint posVAid;   // VBO object ids
    GLuint nrmlVAid;
    GLuint selVAid;
    GLuint texVAid;
    GLuint imgVAid;
    GLuint triangleColorVAid;
    GLuint cellColorVAid;
  
    GLuint pntsVAid;
    GLuint pcolVAid;
    GLuint pselVAid;

    GLuint cellGraphPosVAid;
    GLuint cellGraphColorVAid;

    GLuint axisPosVAid;
    GLuint axisColorVAid;

    GLubyte* texMap;   // Texture map to memory
  
    // Parameters from stack file
    QString Section;
    std::vector<QString> ImageFiles;
  
    QWidget* parent;   // Parent widget
    float min, max;
  
    // Vectors to make heat maps
    float labelWallBordMin;
    float labelWallBordMax;
    QString sigStr;          // Description of heat map
    Point3u clipDo;          // Which clipping planes are selected
    Point4f pn[6];           // Clip planes tranformed into frame coordinates
    HVec4F Hpn;              // Host vector for planes for cuda
    Matrix4d frm;            // Frame matrix
    Matrix4d clm[3];         // Clip plane matrices
    float pixelRadius;       // Radius in frame coordinates of pixel edit tool
    BoundingBox3f bBox;      // Bounding box
    BoundingBox3i bBoxTex;   // Bounding box for texture update
    int marchLabel;          // Label for maching cubes on segmented stack
  
    float meshShift;   // Shift for the mesh, relative to the scene radius
  
    // Variables to marching cubes (for eval)
    HVecUS* marchData;

    // Parameters shared by all instances
    static int ClearColor;
    static uint Slices;
    static uint TileCount;
    static Point3u MaxTexSize;
    static float SurfOffset;
  
    static float DrawNormals;
    static float DrawOffset;
    static float DrawZeroLabels;
    static float DrawNhbds;
    static bool DeleteBadVertex;
    static bool FillWorkData;
    static bool SeedStack;
    static int VoxelEditRadius;
    static int VoxelEditMaxPix;
    static std::vector<Colorf> LabelColors;
    bool LabelColorsChanged;
  
    static bool MeshSelect;
    static ScaleBar scaleBar;
    static Colorbar colorBar;
  
    static float MeshPointSize;
    static float MeshLineWidth;
  
    bool changed;         // Has the stack (mesh) changed
    bool pixelsChanged;   // Changed flag for pixel editing

  public:
    ImgData(int id, QWidget* _parent = 0);
  
    ~ImgData();
  
    void init(Stack* s, Mesh* m);
  
    // Set the internal format of the data
    void setWork16Bit(bool val);
    void setMain16Bit(bool val);
  
    // Set parameters for function
    void readParms(Parms& parms, QString section);
  
    // Set parameters for function
    void writeParms(QTextStream& pout, QString section);
  
    // Get the frame with or without additional transform
    qglviewer::ManipulatedFrame& getFrame() { return stack->getFrame(); }
  
    // Get the main frame
    qglviewer::ManipulatedFrame& getMainFrame() { return stack->frame(); }
  
    // Get the transform frame
    qglviewer::ManipulatedFrame& getTransFrame() { return stack->trans(); }
  
    // Marching cubes evaluation function
    int eval(Point3f p);
  
    // Draw stack data
    void drawStack(Shader* shader);
  
    // Set the file containing the current color map
    void setColorMap(const QString& pth, bool work);
  
    // Update heat histogram
    void updateHeatHistogram();
    // Update surface histogram
    void updateSurfHistogram();
    // Update work histogram
    void updateWorkHistogram();
    // Update main histogram
    void updateMainHistogram();
  
    // Edit the transfer function
    void editMainTransferFunction();
    void editWorkTransferFunction();
    void editSurfTransferFunction();
    void editHeatTransferFunction();
  
    // Update the color map texture
    void updateSurfColorMap() 
    {
      updateColorMap(newSurfColorMap, SurfColorMap, mesh->surfFct());
    }
    void updateHeatColorMap() 
    {
      updateColorMap(newHeatColorMap, HeatColorMap, mesh->heatFct());
    }
    void updateWorkColorMap() 
    {
      updateColorMap(newWorkColorMap, WorkColorMap, stack->work()->transferFct());
    }
    void updateMainColorMap() 
    {
      updateColorMap(newMainColorMap, MainColorMap, stack->main()->transferFct());
    }
    void updateColorMap(bool& newColorMap, std::vector<TransferFunction::Colorf>& ColorMap,
                        const TransferFunction& transferFct);
  
    // Setup color map to use in draw
    void setupSurfColorMap() 
    {
      setupColorMap(newSurfColorMap, surfTexId, SurfColorMap, Shader::AT_SURF_TEX);
    }
    void setupHeatColorMap() 
    {
      setupColorMap(newHeatColorMap, heatTexId, HeatColorMap, Shader::AT_HEAT_TEX);
    }
    void setupMainColorMap() 
    {
      setupColorMap(newMainColorMap, mcmapTexId, MainColorMap, Shader::AT_CMAP_TEX);
    }
    void setupMainColorMap2() 
    {
      setupColorMap(newMainColorMap, mcmapTexId, MainColorMap, Shader::AT_SECOND_CMAP_TEX);
    }
    void setupWorkColorMap() 
    {
      setupColorMap(newWorkColorMap, wcmapTexId, WorkColorMap, Shader::AT_CMAP_TEX);
    }
    void setupWorkColorMap2() 
    {
      setupColorMap(newWorkColorMap, wcmapTexId, WorkColorMap, Shader::AT_SECOND_CMAP_TEX);
    }
    void setupLabelColorMap()
    {
      std::vector<TransferFunction::Colorf> empty;
      bool nonew = false;
      setupColorMap(nonew, labelTexId, empty, Shader::AT_LABEL_TEX);
    }
    void setupColorMap(bool& newColorMap, GLuint& cmapTexId, 
          const std::vector<TransferFunction::Colorf>& ColorMap, Shader::ActiveTextures activeTex);

    // Setup a 1D texture from a color map vector
    bool setupTexFromColorMap(GLuint &texId, const ColorbVec &colorVec);
  
    // Draw mesh wireframe
    void drawMesh();
  
    // Draw lines joining corresponding vertices
    void drawVertexVertexLine(ImgData* stack);
  
    // Draw cell axis
    void drawAxis();
  
    // Draw Bounding Box around the stack
    void drawBBox();
  
    // Setup the uniforms and textures to render 3D data
    void setup3DRenderingData(Shader* shader);
  
    // Draw mesh shaded
    // - select renders unique colors in select frame buffer
    // - optionally pass shaders (not needed for select mode)
    void drawSurf(bool select, Shader* textureShader = 0, Shader* labelShader = 0, 
                                      Shader *colorShader = 0, Shader* volumeShader = 0);

    bool showOpaqueSurface() 
    {
      return mesh->showSurface() and !mesh->blending();
    }
  
    bool showTransparentSurface() 
    {
      return mesh->showSurface() && mesh->blending() && (mesh->opacity() > 0.0);
    }
  
    void setupVolumeShader(Shader& shader, int pos);
  
    // Setup data for clipping test
    void getClipTestData(ClipRegion& clip1, ClipRegion& clip2, ClipRegion& clip3);
  
    // Test if a point (in image coordinates) is inside clipping planes
    bool clipTest(const Point3i& ip);
  
    // Reset stack data
    void resetStack();
  
    // Reset mesh data
    void resetMesh();
  
    // Initialize controls
    void initControls(QWidget* viewer);
  
    // Texture management
    void unloadTex();
    void loadTex();
    void reloadLabelTex();
    void reloadMainTex(const BoundingBox3i& bbox = BoundingBox3i());
    void reloadWorkTex(const BoundingBox3i& bbox = BoundingBox3i());
    void reloadTex(GLuint texId);
    void updateTex(GLuint texId, BoundingBox3i bBox);
    void initTex();
    void bind3DTex(GLuint texId, Shader::ActiveTextures atexId = Shader::AT_TEX3D);
    void bind2DTex(GLuint texId);
    void unbind3DTex();
    void unbind2DTex();
    void loadImgTex(const QImage& image);
  
    // Fill selected color with current label (bucket icon)
    void fillLabel(const IntSet &label, int currlabel);
  
    // Set parent label
    void setParent(int label, int parentLabel);
    void setParent(const IntSet &labels, int parentLabel);
  
    // Select the vertices for given label
    void selectLabel(int label, int repeat = 0);
    void selectLabel(const IntSet &labels);
  
    // Unselect the vertices for given label
    void unselectLabel(const IntSet &labels);
  
    // Select the vertices for given parent
    void selectParent(int label, int repeat = 0);
    void selectParent(const IntSet &labels);
  
    // Unselect the vertices for given parent
    void unselectParent(const IntSet &parents);
  
    // Select connected vertices
    void selectConnected(std::vector<uint> &vlist, bool unselect);
  
    // Select vertices
    void selectVertices(std::vector<uint> &vlist, bool unselect);

    // Put label on a list of vertices (a triangle)
    void addSeed(int label, const std::vector<uint> &vlist);

    // Draw signal on the mesh
    void drawSignal(int signal, const std::vector<uint> &vlist);
  
    // Fill selection with current
    void fillSelect(int label);
  
    // Delete selected vertices
    void deleteLabel(int label);
  
    // Update points, set save ids, and count triangles for VBOs
    void updatePoints(uint &VCount, uint &LCount, uint &TCount);
  
    // Update only the position for points and lines
    void updatePos();
  
    // Search through the mesh and increase the next label if required
    void updateNextLabel();
  
    // Update triangle texture coords
    void updateTriColor();
  
    // Update points and lines and the selection
    void updateLines();
  
    // Update positions
    void updateTriPos();

    // Update the colors for selection
    void updateSelectTris(); 

    // Update the texture for height map (Keyence) data
    void updateImageTex2d();

    // Update the cell graph
    void updateCellGraph();

    // Update the cell graph
    void updateAxis();

    // Fill the vertex array
    void fillVBOs();

    // Start select framebuffer 
    bool startSelectFbo();
  
    // Stop select framebuffer 
    bool stopSelectFbo();
  
    // Stop select framebuffer 
    bool readSelectFbo();
  
    // Correct the selection
    void correctSelection(bool inclusive);
  
    // Update the selection array
    void updateSelection();
  
    // Update Color and texture vertex array
    void updColorVBOs();

    // Find selected triangle in triangle select mode (!MeshSelect)
    void findSelectTriangle(uint x, uint y, std::vector<uint>& vlist, int& label, 
                                                     bool useParentLabel = true);
    // Average a list of vertices to find select point
    bool findSeedPoint(uint x, uint y, CutSurf& cutSurf, Point3f& p);
  
    // Clear mesh selection
    void clearMeshSelect();
  
    // Add point to selection
    void addSelect(const VtxVec &vList);
  
    // Remove points from selection
    void removeSelect(const VtxVec &vlist);
  
    // Apply a single clip plane to the bounding box
    void bBoxClip(BoundingBox3f& bBox, Point3f p, Point3f n);
  
    // Make a bounding box from the clipping planes
    void bBoxFromClip();
  
    // Start pixel editing
    void voxelEditStart(ClipRegion& clip1, ClipRegion& clip2, ClipRegion& clip3);
  
    // Pixel editing operations
    // p, px, py and pz should be in world coordinates
    void voxelEdit(float pixelRadius, const Point3f& p, const Point3f& px, const Point3f& py, 
                                      const Point3f& pz, bool doCut, int currentLabel);
  
    // Stop pixel editing
    void voxelEditStop();
  
    bool isMainVisible() const 
    {
      return stack->main()->isVisible() and mainDataTexId;
    }
    bool isWorkVisible() const 
    {
      return stack->work()->isVisible() and workDataTexId;
    }
    bool isVisible() const 
    {
      return isMainVisible() or isWorkVisible();
    }
  
    HVecUS& currentData()
    {
      if(stack->work()->isVisible())
        return stack->work()->data();
      return stack->main()->data();
    }
    const HVecUS& currentData() const
    {
      if(stack->work()->isVisible())
        return stack->work()->data();
      return stack->main()->data();
    }
    Point3f imageGradientW(Point3d worldpos);
    Point3f imageGradientI(Point3i ipos);
    uint imageLevel(Point3d worldpos);
    Point2i imageMinMax();
  
    GLenum interpolation(GLuint texId)
    {
      if(texId == workDataTexId)
        return stack->work()->labels() ? GL_NEAREST : GL_LINEAR;
      else
        return stack->main()->labels() ? GL_NEAREST : GL_LINEAR;
    }
  
    GLenum internalFormat(GLuint texId)
    {
      if(texId == workDataTexId)
        return Work16Bit ? GL_ALPHA16 : GL_ALPHA8;
      else
        return Main16Bit ? GL_ALPHA16 : GL_ALPHA8;
    }
  
    GLenum swapTextureBytes(GLuint texId)
    {
      if(texId == workDataTexId)
        return stack->work()->labels();
      else
        return stack->main()->labels();
    }
  
    // Set stack sizes
    void updateStackSize();
  
    // Change the texture scale of the stack
    void setTexScale(float s);
  
    bool valid() const 
    {
      return stack->storeSize() > 0 and (mainDataTexId or workDataTexId);
    }
  
  protected:
    // Update a list of vertex labels
    void updLabel(int label, const std::vector<uint> &vlist);
  
    // Update a list of vertex labels
    void updSignal(int signal, const std::vector<uint> &vlist);
  
    // Load 3D texture data, possibly downsampling.
    void load3DTexData(const GLuint texId, const Point3u size, const ushort* data);
  
    // Get step for texture decimation
    Point3u getTexStep();
  
  public:
    // Clip texture coordinates
    float trimTex(const float val) { return (trim(val, 0.0f, 1.0f)); }
  
    Point2f trimTex(const Point2f& val) { return (Point2f(trimTex(val.x()), trimTex(val.y()))); }
  
  protected:
  
    // Test if quad out of bounds, used for clipping 3D data
    bool testQuad(float a, float b, float c, float d, float x)
    {
      if(a > x and b > x and c > x and d > x)
        return (true);
      if(a < -x and b < -x and c < -x and d < -x)
        return (true);
      return (false);
    }
  
    // Get point color
    Point3GLub pColor(const vertex& v)
    {
      // Get the color
      Color3f c;
      if(v->selected)
        c = Colors::getColor(MeshSelectColor);
      else if(v->minb != 0 or v->label < 0)
        c = Colors::getColor(MeshBorderColor);
      else
        c = Colors::getColor(MeshColor);
  
      return (Point3GLub(255 * c.x(), 255 * c.y(), 255 * c.z()));
    }
  
    // Get line color, and if it should be drawn
    bool lDraw(const vertex& a, const vertex& b)
    {
      // Choose which line to draw
      if(mesh->meshView() == "Border" and !(a->margin and b->margin))
        return false;
      if(mesh->meshView() == "Cells" and !(a->label == -1 and b->label == -1))
        return false;
      return true;
    }
  
    // Compute offset for image data including border
    size_t offset(uint x, uint y, uint z) { return stack->offset(x, y, z); }
  
    size_t offset(Point3i ipos) { return stack->offset(ipos); }
  
    // Check if in bounds
    bool boundsOK(int x, int y, int z)
    {
      if(x < 0 or y < 0 or z < 0 or x >= int(stack->size().x()) or y >= int(stack->size().y())
         or z >= int(stack->size().z()))
        return (false);
      else
        return (true);
    }
  
  public:
    /// Go from image coordinates to world coordinates
    template <typename T> Point3f imageToWorld(const Vector<3, T>& img) const
    {
      return stack->imageToWorld<T>(img);
    }
  
    /// Go from world coordinates to image coordinates
    template<typename T> Vector<3, T>worldToImage(Point3f wrld) const { return stack->worldToImage<T>(wrld); }
    Point3f worldToImagef(const Point3f& a) const { return worldToImage<float>(a); }
    Point3i worldToImagei(const Point3f& a) const { return worldToImage<int>(a); }
    Point3u worldToImageu(const Point3f& a) const { return worldToImage<uint>(a); }
  
    // Map scale slider values
    int toSliderScale(float s);
    float fromSliderScale(int i);
  
  protected:
    void updateHistogram(std::vector<double>& hist, const HVecUS& data, std::pair<double, double>& minMaxValues,
                         int max_data = 1 << 16, int size = 512);
    void invalidateHistogram(std::vector<double>& hist) { hist.clear(); }
  
    // Clear 3D stack texture
    void clearData(HVecUS& data)
    {
      data.resize(stack->storeSize());
      memset(&data[0], 0, data.size() * sizeof(ushort));
    }
  
    // Return texture info for a vertex with label-based heat
    Point3f texCoordLabels(int label, const vertex & v, const IntFloatAttr & labelHeat);
  
    // Return texture info for a vertex with wall-based heat
    Point3f texCoordWalls(int label, const vertex & v, const vertex & a, const vertex & b, 
                 const vertex & c, const IntIntFloatAttr & wallHeat);
  
    // Set label on triangle
    bool setLabel(vertex v1, vertex v2, vertex v3, int label)
    {
      bool ok = true;
      if(v1->label > 0 and v1->label != label)
        ok = false;
      if(v2->label > 0 and v2->label != label)
        ok = false;
      if(v3->label > 0 and v3->label != label)
        ok = false;
  
      if(ok) {
        if(v1->label == 0)
          v1->label = label;
        if(v2->label == 0)
          v2->label = label;
        if(v3->label == 0)
          v3->label = label;
      }
      return (ok);
    }

  signals:
    void changedInterface();
    void changeSize(const Point3u& size, const Point3f& step, const Point3f& origin);
    void stackUnloaded();
  
  public slots:
    // Update the colors of all points in the mesh
    void updateLineColor();

    // Slots for controls
    void MainShowSlot(bool val);
    void MainBrightSlot(int val);
    void MainOpacitySlot(int val);
    void MainLabelsSlot(bool val);
    void Main16BitSlot(bool val);
    void MainColorMapSlot();
  
    void WorkShowSlot(bool val);
    void WorkBrightSlot(int val);
    void WorkOpacitySlot(int val);
    void WorkLabelsSlot(bool val);
    void Work16BitSlot(bool val);
    void WorkColorMapSlot();
  
    void SurfShowSlot(bool val);
    void SurfBrightSlot(int val);
    void SurfOpacitySlot(int val);
    void SurfBlendSlot(bool val);
    void SurfCullSlot(bool val);
  
    void SurfVertexSlot(bool val);
    void SurfTriangleSlot(bool val);
    void SurfLabelSlot(bool val);

    void VertexViewSlot(const QString &s);
    void TriangleViewSlot(const QString &s);
    void LabelViewSlot(const QString &s);

    void VertexColorMapSlot();
    void TriangleColorMapSlot();
    void LabelColorMapSlot();

    void SurfParentSlot(bool val);
  
    void MeshShowSlot(bool val);
    void ChangeMeshViewModeSlot(const QString &s);
    void AxisShowSlot(bool val);
    void ChangeAxisViewModeSlot(const QString &s);
    void MeshLinesSlot(bool val);
    void MeshPointsSlot(bool val);

    void ViewerUpdateSlot(void);
    void UpdateColorMapSlot(void);
  
    void CellMapSlot(bool val);
    void ShowTransSlot(bool val);
    void ShowScaleSlot(bool val);
    void ShowBBoxSlot(bool val);
    void TieScalesSlot(bool val);   // ALR
    void ScaleSlotX(int val);
    void ScaleSlotY(int val);
    void ScaleSlotZ(int val);
  
    // Slots to change transfer functions
    void setSurfColorMap(const TransferFunction& fct);
    void setHeatColorMap(const TransferFunction& fct);
    void setWorkColorMap(const TransferFunction& fct);
    void setMainColorMap(const TransferFunction& fct);
  
    // Slots to detect changes in transfer fct dialog boxes
    void updateSurfColorMap(const TransferFunction& fct);
    void updateHeatColorMap(const TransferFunction& fct);
    void updateWorkColorMap(const TransferFunction& fct);
    void updateMainColorMap(const TransferFunction& fct);
  
  signals:
    void viewerUpdate();
    void updateSliderScale();
    void forceSurfHeat();
    void toggleEditLabels();
  };
}
#endif
