#include "ShaderProgram.h"

#include "ShaderManager.h"

#include "..\Utilities\Clock.h"
extern void wlog(char* str, ...);

#include <fstream>
#include <sys/stat.h> //fstat stuff

ShaderProgram::ShaderProgram(ShaderManager* const manager, const SHADERTYPE type, const XString& fn)
{
	m_Type = type;
	m_Manager = manager;
	m_Compiled = false;
	m_Filename = fn;
}

void ShaderProgram::Save(const XString& fn)
{
	if(fn.getlen() > 0)
		m_Filename = fn;

	if(m_Filename.getlen() > 0)
	{
		FILE *f;
		fopen_s(&f, m_Filename.getbuffer(), "wt");

		if(!f)
			return;

		fwrite(m_Code.getbuffer(),m_Code.getlen(),sizeof(char),f);

		fclose(f);
	}
}

void ShaderProgram::Open(const XString& fn)
{
	if(m_Filename.getlen() > 0 || fn.getlen() > 0)
	{
		ReadFile(fn);

		Compile(false);
	}
}

void ShaderProgram::Reload(void)
{
	struct _stat64 filestats;
	if (0 == _stat64(m_Filename.getbuffer(), &filestats))
	{
		if (m_ReadedFileSize == filestats.st_size && m_ReadedFileTime == filestats.st_mtime && m_ReadedFileName == m_Filename)
		{
			return;
		}
	}

	Open(m_Filename);
}

void ShaderProgram::ReadFile(const XString& fn)
{
	m_Code = "";

	//CClock asdf;
	//asdf.StartCapture(0);

	struct _stat64 filestats;
	if (0 == _stat64(fn.getbuffer(), &filestats))
	{
		m_ReadedFileSize = filestats.st_size;
		m_ReadedFileTime = filestats.st_mtime;
		m_ReadedFileName = fn;
	}

	FILE *f;
	if (0 == fopen_s(&f, fn.getbuffer(), "rb"))
	{
		fseek(f, 0, SEEK_END);
		int size = ftell(f);
		rewind(f);

		m_Code.SetLength(size);

		fread(m_Code.getbuffer(), sizeof(char), size, f);
			
		//char c;
		//	
		//fread(&c,1,sizeof(char),f);
		//while(!feof(f))
		//{
		//	m_Code.appand(c);
		//	fread(&c,1,sizeof(char),f);
		//}

		fclose(f);

		//wlog("%s", m_Code.getbuffer());
		//wlog("%s", m_Code.getbuffer() + size - 50);
		//wlog("%c%c%c", m_Code.getbuffer()[size-1], m_Code.getbuffer()[size], m_Code.getbuffer()[size+1]);
		//wlog("");
	}

	//asdf.EndCapture(0);
	//double x = asdf.GetCaptureTime(0) * 1000.0 / (double)asdf.GetTicksPerSec();
	//x = x;

	//wlog("FXRead: %f", (float)x);
}

ShaderProgram::~ShaderProgram(void)
{
	//ReleaseSH(); doesnt call virtual function
	m_Manager->Release(this);
}