//
// myunique.cpp
//

//#include "lsh_mex_functions.h"
#include <mex.h>
#include <hash_map>

void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
	if (nrhs != 1)
	{
		mexErrMsgTxt("Please provide 1 inputs 1st - array of uin32");
	}
	if (nlhs > 2)
	{
		mexErrMsgTxt("Two output provided (unique vals and index).");
	}
	if (!mxIsUint32(prhs[0]))
	{
		mexErrMsgTxt("First input must be a unsigned int 32 scalar or array.");
	}
        
    stdext::hash_map<unsigned int, unsigned int> m;           
	unsigned int num_of_points = std::max(mxGetM(prhs[0]),mxGetN(prhs[0]));
    unsigned int* p = (unsigned int*)mxGetData(prhs[0]);
    
    for (int i=0;i<num_of_points;i++) {
        m.insert(std::pair<unsigned int, unsigned int>(*p,i+1));
        p++;
    }
    
    plhs[0] = mxCreateNumericMatrix(1, m.size(), mxUINT32_CLASS, mxREAL);
    unsigned int* u = (unsigned int*)mxGetData(plhs[0]);    
        
    unsigned int* index = NULL;
    if (nlhs > 1) {
        plhs[1] = mxCreateNumericMatrix(1, m.size(), mxUINT32_CLASS, mxREAL);
        index = (unsigned int*)mxGetData(plhs[1]);
    }
    
    stdext::hash_map<unsigned int, unsigned int>::const_iterator it_end = m.end();
    if (index) {
        for (stdext::hash_map<unsigned int, unsigned int>::const_iterator it = m.begin(); it != it_end;it++) {
            *(u++) = it->first;
            *(index++) = it->second;
        }
    } else {
        for (stdext::hash_map<unsigned int, unsigned int>::const_iterator it = m.begin(); it != it_end;it++) {
            *(u++) = it->first;
        }
    }
}
