#include "Stdafx.h"
#include "Mat.h"

namespace Domination {
	namespace Unmanaged {
		namespace OpenCV 
		{
			Mat::Mat()
			{
				ref = new cv::Mat();
			}
			Mat::Mat(int rows, int cols, int type)
			{
				ref = new cv::Mat(rows, cols, type);
			}
			Mat::Mat(int rows, int cols, MatrixType type)
			{
				ref = new cv::Mat(rows, cols, (int)type);
			}

			Mat::~Mat()
			{
				delete ref;
				this->!Mat();
			}

			Mat::!Mat()
			{
				//System::Console::WriteLine("release resource");
			}

			size_t Mat::total()
			{
				return ref->total();
			}
			size_t Mat::elemSize()
			{
				return ref->elemSize();
			}
			size_t Mat::elemSize1()
			{
				return ref->elemSize1();
			}
			int Mat::type()
			{
				return ref->type();
			}
			int Mat::depth()
			{
				return ref->depth();
			}
			int Mat::channels()
			{
				return ref->channels();
			}

			Mat^ Mat::zeros(int rows, int cols, int type)
			{
				Mat^ mat = gcnew Mat();
				*mat->ref = cv::Mat::zeros(rows, cols, type);
				return mat;
			}

			generic <typename T> 
			cli::array<T, 1>^ Mat::ToArray()
			{
				size_t length = ref->total();
				cli::array<T, 1>^ buffer = gcnew cli::array<T, 1>((int)length);

				if(ref->elemSize() == 1)
				{
					//pin_ptr<T> bufferPtr = &buffer[0];
					//memcpy(bufferPtr, ref->ptr(), length);
					for(int i = 0; i < length; i++)
					{
						unsigned char c = ref->at<unsigned char>(i);
						buffer[i] = (T)((unsigned char)c);
					}
				}
				else if(ref->elemSize() == 3)
				{
					for(int i = 0; i < length; i++)
					{
						char b = ref->at<char>(3 * i);
						char g = ref->at<char>(3 * i + 1);
						char r = ref->at<char>(3 * i + 2);

						buffer[i] = (T)(65536 * r + 256 * g + b);
					}
				}
				return buffer;
			}
		}
	}
}