#ifndef CELL_ATLAS_PRIMORDIUM_HPP
#define CELL_ATLAS_PRIMORDIUM_HPP

#include <CellAtlasConfig.hpp>

#include <Process.hpp>
#include <RootCellAnalyzing.hpp>
#include <RootCellProcessing.hpp>
#include <CellAtlas.hpp>



using namespace std;

namespace mgx 
{
  static RootCellProcessing rcp;

  // for attribute maps
  struct CellAtlasPrimordiumData{

  };

   class CellAtlas_EXPORT AnalyzeLeafPrimSurf : public Process
  {
    public:
      AnalyzeLeafPrimSurf(const Process& process) : Process(process) 
      { 
		setName("Mesh/Cell Atlas 3D/Stack/Analyze Leaf Primordium");
		setDesc("Analyzes the primordium, select vertices on the surface mesh at the side of the origin of the coordinate system");  
		setIcon(QIcon(":/images/CellAtlas.png"));		  
	  }

      bool run(){
        const Stack *s1 = currentStack();//stack(0);
        if(!checkState().mesh())
          return false;
        Mesh *m = currentMesh();
        if(currentMesh() == mesh(0)){
          //cout << "s1" << endl;
          return run(s1, m, rcp.prim1);
        } else {
          //cout << "s2" << endl;
          return run(s1, m, rcp.prim2);
        }
        
      }
      bool run(const Stack *s1, Mesh *m1, primDataStructure& p);

  };

  // run analyzeLeafPrim on mesh1 and mesh2 first
  // then project stack1 onto stack2 (which will be generated in the process)
  class CellAtlas_EXPORT ProjectLeafPrimStack : public Process
  {
    public:
      ProjectLeafPrimStack(const Process& process) : Process(process) 
      { 
		setName("Mesh/Cell Atlas 3D/Stack/Project Leaf Prim Stack");
		setDesc("Analyzes the primordium");
		setIcon(QIcon(":/images/CellAtlas.png"));
		
		addParm("Quality","Quality","500");  		  
	  }

      bool run(){

        Stack* s1 = stack(0);
        Stack* s2 = stack(1);
        Store* input = s1->currentStore();
        //Store* output = s2->currentStore();
        Store* output = s2->work();

        primDataStructure &p1 = rcp.prim1;
        primDataStructure &p2 = rcp.prim2;

        return run(s1, s2, input, output, p1, p2, parm("Quality").toInt());
      }
      
      bool run(Stack* s1, Stack* s2, Store* input, Store* output, primDataStructure &cellData1, primDataStructure &cellData2, int threshold);

  };

  class CellAtlas_EXPORT CellAtlasStack : public Process
  {
  public:
    CellAtlasStack(const Process& process) : Process(process) 
    {
	  setName("Mesh/Cell Atlas 3D/Stack/Longitudinal Signal Histogram");
	  setDesc("TBD");
	  setIcon(QIcon(":/images/MakeHeatMap.png"));

	  addParm("Bin Size","Bin Size","1.0");
	  addParm("Rad Min","Rad Min","0.0");
	  addParm("Rad Max","Rad Max","1.0");
	  addParm("Rad Type","Rad Type","absolute");
	  addParm("Save to File","Save to File","");
	  addParm("Voxel Cube Size","Voxel Cube Size","1");		
	}
		
    bool processParms();

    bool run()
    {
      Stack* s1 = currentStack();
      Store* store1 = s1->main();
      Store* store2 = s1->work();
      Mesh* m = currentMesh();
      return run(s1, store1, store2, m, parm("Bin Size").toDouble(), parm("Rad Min").toDouble(), parm("Rad Max").toDouble(), parm("Rad Type"), parm("Save to File"), parm("Voxel Cube Size").toInt());
    }
    
    bool run(Stack* s1, Store* store1, Store* store2, Mesh* m, double binSize, double radMin, double radMax, QString radType, QString filename, int cubeSize);

  };


}

#endif
