//
// 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 GLOBALPROCESS_HPP
#define GLOBALPROCESS_HPP

#include <Process.hpp>

namespace mgx
{
  ///\addtogroup Stack Processes
  ///@{
  /**
   * \class SetCurrentStack GlobalProcess.hpp <GlobalProcess.hpp>
   *
   * Set the current stack and store. This process is meant to be used when scripting.
   */
  class mgxBase_EXPORT SetCurrentStack : public Process 
  {
  public:
    SetCurrentStack(const Process& process) : Process(process) 
    {				
      setName("Stack/System/Set Current Stack");
      setDesc("Change the current stack and mesh. Needed for scripts.");
      setIcon(QIcon(":/images/Relabel.png"));
    
      addParm("Store","Current store, or 'Both'","Main", QStringList() << "Main" << "Work" << "Both" << "None");
      addParm("Stack id","Stack id","0");						
  }
  
    bool run()
    {
      bool is_main = stringToMainStore(parm("Store"));
      int id = parm("Stack id").toInt();
      return run(parm("Store"), id);
    }
  
    bool run(const QString &store, int id);
  };
  
  /**
   * \class SaveGlobalTransform GlobalProcess.hpp <GlobalProcess.hpp>
   *
   * Save the transformation from stack 1 to stack 2 in a file. The file contains 16 numbers:
   *
   * ``m11 m21 m31 m41 m21 m22 m23 m24 m31 m32 m33 m34 m41 m42 m43 m44``
   *
   * The transformation is then defined by the matrix:
   *
   * \f$ M = \left[\begin{array}{cccc} m11 & m12 & m13 & m14 \\
   *                                  m21 & m22 & m23 & m24 \\
   *                                  m31 & m32 & m33 & m34 \\
   *                                  m41 & m42 & m43 & m44 \end{array} \right] \f$
   */
  class mgxBase_EXPORT SaveGlobalTransform : public Process {
    Q_OBJECT
  
  public:
    SaveGlobalTransform(const Process& process) : Process(process) 
    {
				
      setName("Misc/Transform/Save Global Transform");
      setDesc("Save the global alignment (transform) matrix from one stack to the other into a file");
      
	  setIcon(QIcon(":/images/save.png"));
      addParm("Filename","Filename","");						
	}
  
    bool initialize(QWidget* parent);
  
    bool run() { return run(parm("Filename")); }
  
    bool run(const QString& filename);
  };
  
  /**
   * \class JoinRegionsSegment GlobalProcess.hpp <GlobalProcess.hpp>
   *
   * Join regions, using both the segmented stack and the extracted 3D cell mesh.
   *
   * Starting from a segmented stack, and the 3D cell mesh created from it, the
   * user can select a set of cells that needs to be merged. This process will
   * create a new cell corresponding to the union of all the selected cells and
   * rerun the Marching Cube process with the provided cube size.
   */
  class mgxBase_EXPORT JoinRegionsSegment : public Process {
  public:
    JoinRegionsSegment(const Process& process) : Process(process) 
    {
      setName("Stack/Segmentation/Join Regions");
      setDesc("Join Regions after 3D segmentation.Cells selected in the 3D cell mesh extracted from the stack will be merged and re-extracted.");
	  setIcon(QIcon(":/images/JoinRegions.png"));
	  
      addParm("Cube Size","Cube Size for the Marching Cube process.","0");				
	}
  
    bool run()
    {
      if(!checkState().store(STORE_WORK | STORE_LABEL).mesh(MESH_NON_EMPTY))
        return false;
      Store* work = currentStack()->work();
      Mesh* mesh = currentMesh();
  
      bool ok;
      float cubeSize = parm("Cube Size").toFloat(&ok);
      if(not ok)
        return setErrorMessage("Error, the parameter 'Cube Size' must be a number.");
  
      bool res = run(work, mesh, cubeSize);
      if(res)
        work->show();
      return res;
    }
  
    bool run(Store* work, Mesh* mesh, float cubeSize);
  };
///@}
}

#endif
