/*
This work is part of the Core Imaging Library developed by
Visual Analytics and Imaging System Group of the Science Technology
Facilities Council, STFC

Copyright 2017 Srikanth Nagella, Edoardo Pasca

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

 #ifndef CILSEGMENTATION_H
 #define CILSEGMENTATION_H

#include "HeightField.h"
#include "CCPiDefines.h"
#include <vector>
#include <utility>
#include <algorithm>

#include "boost/tuple/tuple.hpp"

class CCPI_EXPORT CilContourTreeSegmentation {
private:
	HeightField * field;
	float isoValue;
	int sampleSize;
	Array3D<unsigned char> rawData_char;
	Array3D<unsigned short> rawData_short;
	int axisOrder[3];
	template<typename T>
	void SetInputData(T * datablock) {

		int dims[3]; 
		dims[0]= (int) datablock->XDim();
		dims[1]= (int) datablock->YDim();
		dims[2]= (int) datablock->ZDim();

		field->SetInputData(datablock, dims, sampleSize);
	}
	template<typename T>void SetInputDataBlock(T * datablock, int * dims) {

		field->SetInputDataBlock(datablock, dims, sampleSize);
	}
public:
    
	CilContourTreeSegmentation();
	~CilContourTreeSegmentation();
	void CreateImageData(int * dims, int sampleSize);
	void CreateImageData(int * dims, int sSize, void * datapointer);
	boost::tuple<int, int, int> GetDimensions();
	void SetPixelValueAt(int * pixel, void * pvalue);
	void PassImageData();
	void PassImagePointer();
	void SetPixelValueAt(int x, int y, int z, void * pvalue);
	void SetPixelValueAtIndex(long index, void * pvalue);
	void SetIsoValue(float);
	void SetIsoValuePercent(int);
	void SetIsoValuePercentFloat(float);
	void SingleUnCollapse();
	void SingleCollapse();

	unsigned short GetPixelValueAt(int x, int y, int z);
	unsigned short GetPixelValueAtIndex(long index);
	float GetIsoValue();

	void CalculateContourTree();
	void ConstructIsoSurface();
	float GetMin();
	float GetMax();
	vector<float> GetTrianglePoints();
	vector<int> GetSurfaceLastPoints();
	boost::tuple<int, int, int> GetSurface(int);
	std::vector<boost::tuple<int, int, int> > GetSurfaces();
	vector<float> GetWorldCoordinatesOfPointsOfSurface(int, double*);
	int GetSampleSize();
	void SetAxisOrder(int , int , int);
	int * GetAxisOrder();

	void SetCollapsePriority(int);
	void ResetCollapsePriority(int);
	int GetCollapsePriority();
	std::vector<boost::tuple<long, long, long> > GetContourTree3D();
	std::vector<boost::tuple<float, float> > GetContourTree2D();


	void SetLogPriorityBound(float);
	void SetLogTreeSize(float);


	float GetLogPriorityBound();
	float GetLogTreeSize();

	void UpdateFromLogPriorityBound();
	void UpdateFromLogTreeSize();
};


 #endif
