// ResTreeView.cpp : implementation file
//

#include "stdafx.h"
#include "ResourceBrowser.h"
#include "ResourceBrowserDoc.h"
#include "ResTreeView.h"
#include "ReportDlg.h"
#include <Adept\Adept.hpp>
#include <Stuff\Stuff.hpp>
#include <MW4\MW4.hpp>

using namespace Stuff;
using namespace Adept;
using namespace MechWarrior4;


/////////////////////////////////////////////////////////////////////////////
// CResTreeView

IMPLEMENT_DYNCREATE(CResTreeView, CTreeView)

CResTreeView::CResTreeView()
{
	m_dwDefaultStyle |= TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS;
}

CResTreeView::~CResTreeView()
{
}


BEGIN_MESSAGE_MAP(CResTreeView, CTreeView)
//{{AFX_MSG_MAP(CResTreeView)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
ON_COMMAND(ID_TOOLS_UNRESOURCEIFIEDREPORT, OnToolsUnresourceifiedreport)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CResTreeView drawing

void CResTreeView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CResTreeView diagnostics

#ifdef _DEBUG
void CResTreeView::AssertValid() const
{
	CTreeView::AssertValid();
}

void CResTreeView::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CResTreeView message handlers

BOOL CResTreeView::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	return CTreeView::OnChildNotify(message, wParam, lParam, pLResult);
}

void CResTreeView::OnInitialUpdate() 
{
	CTreeView::OnInitialUpdate();
	char path[MAX_PATH];
	GetCurrentDirectory(MAX_PATH,path);
	AddDirectory(CString(path),CString("Content"));
	
}

void CResTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	CResourceBrowserDoc *doc=(CResourceBrowserDoc *)GetDocument();
	doc->m_CurPath="";
	BuildPath(doc->m_CurPath,pNMTreeView->itemNew.hItem);
	doc->UpdateAllViews(this);
	*pResult = 0;
}

void CResTreeView::AddDirectory(CString &basepath,CString &dir,HTREEITEM par)
{
	
	HTREEITEM itm;
	
	itm=GetTreeCtrl().InsertItem(dir,par);
	
	WIN32_FIND_DATA file_data;
	HANDLE file_find;
	file_find=FindFirstFile(basepath+"\\"+dir+"\\*.*",&file_data);
	
	if(file_find != INVALID_HANDLE_VALUE)
	{
		CString dir_name;
		do
		{
			dir_name=file_data.cFileName;
			if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY && 
				dir_name!="."  && dir_name!=".." )
			{
				AddDirectory(basepath+"\\"+dir,dir_name,itm);
			}
		}
		while (FindNextFile(file_find,&file_data));
	}
	
	
}

void CResTreeView::BuildPath(CString &str, HTREEITEM itm)
{
	if(itm!=NULL)
	{
		str=GetTreeCtrl().GetItemText(itm)+"\\"+str;
		BuildPath(str,GetTreeCtrl().GetParentItem(itm));
	}
}

void CResTreeView::UnResReportOnDir(NotationFile *note_file,CString dir)
{
	Page *page=NULL;
	WIN32_FIND_DATA file_data;
	HANDLE file_find;
	file_find=FindFirstFile(dir+"*.*",&file_data);
	
	CString file_name;
	
	if(file_find != INVALID_HANDLE_VALUE)
	{
		do
		{
			file_name=file_data.cFileName;
			int count = 0;
			if(!(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && 
				file_name.CompareNoCase("vssver.scc") && 
				!InResources(dir+file_name))  
			{
				if(!page) page=note_file->AddPage(dir);
				
				page->SetEntry(dir+file_name,"no");
			}
		}
		while (FindNextFile(file_find,&file_data));
	}
	
	file_find=FindFirstFile(dir+"*.*",&file_data);
	
	
	if(file_find != INVALID_HANDLE_VALUE)
	{
		do
		{
			file_name=file_data.cFileName;
			int count = 0;
			if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY && file_name!="."  && file_name!="..")
			{
				UnResReportOnDir(note_file,dir+file_name+"\\");
			}
		}
		while (FindNextFile(file_find,&file_data));
	}
	
	
	
}

void CResTreeView::OnToolsUnresourceifiedreport() 
{
	CReportDlg rdlg;
	
	if(rdlg.DoModal()==IDOK)
	{
		NotationFile report;
		report.DeleteAllPages();
		switch(rdlg.m_TList)
		{
		case 0: UnResReportOnDir(&report,"Content\\"); break;
		case 1: MultiResReport(&report); break;
		}
		
		report.SaveAs(rdlg.m_DPath);
		MessageBox("Report Complete","All Done",MB_OK);
	}	
	
}

void CResTreeView::MultiResReport(Stuff::NotationFile *note_file)
{
	if(Adept::ResourceManager::Instance==NULL) return;
	Adept::Resource curres;
	curres.First(NULL);
		Page *statpage=note_file->SetPage("FINAL STATS");
	
	
	CString res_name,base_name,dir_name;
		int totaldups=0;
		int totaldupsize=0;
		int totaldupcomsize=0;

	while(curres.ReadAndNext())
	{
		const char *resname=curres.GetName();
		
		short rfilenum;
		
		CString FirstDep;
		
		int count=0;
			CString filename;
		for(rfilenum=0;rfilenum<FreeId;rfilenum++)
		{
			ResourceFile *rfile=ResourceManager::Instance->GetResourceFile(rfilenum);
			Resource res(resname,rfile);
			if(res.DoesResourceExist())
			{
				filename=ResFileNames[rfilenum];
				count++;
					if(count==1)
					{
						if(res.GetResourceID()!=curres.GetResourceID()) break; 
						FirstDep=filename;
					}
					else if(count==2)
					{
					totaldups++;
						Page *page=note_file->SetPage(resname);
					page->SetEntry(FirstDep,(int)res.GetSize());
					}
					
					if(count>1)
					{
					totaldupsize+=res.GetSize();
					totaldupcomsize+=res.GetCompressedSize();
					Page *page=note_file->SetPage(resname);
					page->SetEntry(filename,(int)res.GetSize());
					}

					}
				
			}
		}
		
		statpage->SetEntry("Duplicate files",totaldups);
		statpage->SetEntry("Duplicate bytes(uncompressed)",totaldupsize);
		statpage->SetEntry("Duplicate bytes(On Disk)",totaldupcomsize);
		statpage->SetEntry("Compression Ratio",(Scalar)totaldupsize/totaldupcomsize);
	}
	


bool CResTreeView::InResources(CString &str)
{
	Adept::Resource res(str);
	return res.DoesResourceExist();
	
}
