// AnimSizeDlg.cpp : implementation file
//

#include "stdafx.h"
#include "AnimSize.h"
#include "AnimSizeDlg.h"

#include "Stuff\NotationFile.hpp"

#if !defined(STUFF_STUFF_HPP)
	#include "Stuff\Stuff.hpp"
#endif


#include <GameOS\GameOS.hpp>
#include <DLLPlatform\DLLPlatform.hpp>

#if !defined(MW4ANIMATIONSYSTEM_HPP)
	#include <MW4\MW4AnimationSystem.hpp>
#endif

HGOSHEAP Heap;
using namespace Stuff;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



#include "AnimDetail.h"

using namespace MW4Animation;

/////////////////////////////////////////////////////////////////////////////
// CAnimSizeDlg dialog

CAnimSizeDlg::CAnimSizeDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CAnimSizeDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CAnimSizeDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	HINSTANCE	hInstance;
	hInstance = AfxGetResourceHandle();

	InitGameOS( hInstance, NULL, "\0" );


	Stuff::ArmorLevel = 3;

	Stuff::InitializeClasses();


	notationList = NULL;
	notNamed = false;


	iconList = new CImageList;
	Register_Pointer(iconList);

	iconList->Create(16,16, ILC_COLOR16, 2,2);

	iconList->Add( theApp.LoadIcon( IDI_ICON_NOT_LOADED ));
	iconList->Add( theApp.LoadIcon( IDI_ICON_LOADED		));

	Heap = gos_CreateMemoryHeap("Default");
	Check_Pointer(Heap);
	gos_PushCurrentHeap(Heap);
	
}

CAnimSizeDlg::~CAnimSizeDlg()
{

	gos_PopCurrentHeap();

	Unregister_Pointer(iconList);
	delete iconList;
	iconList = NULL;

	Stuff::TerminateClasses();
//	DLLPlatform::TerminatePlatform();

	ExitGameOS();

}



void CAnimSizeDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAnimSizeDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAnimSizeDlg, CDialog)
	//{{AFX_MSG_MAP(CAnimSizeDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON2, OnLoad)
	ON_BN_CLICKED(IDC_BUTTON3, OnSave)
	ON_BN_CLICKED(IDC_BUTTON4, OnAddFiles)
	ON_BN_CLICKED(IDC_BUTTON5, OnRefresh)
	ON_BN_CLICKED(IDC_BUTTON6, OnQuit)
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_BUTTON_DETAIL, OnButtonDetail)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAnimSizeDlg message handlers


#define NAME_COLUMN 0
#define CHANNEL_COUNT_COLUMN 1
#define SIZE_COLUMN 2


int ColumnArray[3];

BOOL CAnimSizeDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	CListCtrl *list = (CListCtrl *)GetDlgItem( IDC_ANIM_LIST );
	ColumnArray[NAME_COLUMN] = list->InsertColumn( NAME_COLUMN, "Name", LVCFMT_LEFT, 350);
	ColumnArray[CHANNEL_COUNT_COLUMN] = list->InsertColumn( CHANNEL_COUNT_COLUMN, "Channels", LVCFMT_LEFT, 60);
	ColumnArray[SIZE_COLUMN] = list->InsertColumn( SIZE_COLUMN, "Size", LVCFMT_LEFT, 50);


	list->SetImageList(iconList, LVSIL_SMALL);


	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CAnimSizeDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CAnimSizeDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}
/////////////////////////////////////////////////////////////////////////////

void CAnimSizeDlg::OnLoad() 
{

	// save current list
	if (notationList != NULL)
	{
		int result = CAnimSizeDlg::MessageBox("Do you want to save current list?", "Save", MB_YESNOCANCEL);

		if (result == IDYES)
		{
			const char *name = NULL;
			if (!notNamed)
			{
				name = notationList->GetFileName();
			}

			CFileDialog dlg(false, ".list", name, OFN_OVERWRITEPROMPT, "Notation List (*.list)|*.list||");


			if (dlg.DoModal() == IDOK)
			{
				

				//Stuff::FileStream file_stream(dlg.GetPathName(), Stuff::FileStream::WriteOnly);
	
				notationList->SaveAs(dlg.GetPathName());

				//notationList->Reset();
				Unregister_Object(notationList);
				delete notationList;
				notationList = NULL;
	
			}
			else
			{
				return;
			}
		}
		else if (result == IDNO)
		{
			notationList->IgnoreChanges();
			Unregister_Object(notationList);
			delete notationList;
			notationList = NULL;
		}
		else
		{
			return;
		}
	}

	Verify(notationList == NULL);
	// load new list

	CFileDialog dlg(true, ".list", NULL, NULL, "Notation List (*.list)|*.list||");

	if (dlg.DoModal() == IDOK)
	{
		
		notationList = new NotationFile(dlg.GetPathName());
		Register_Object(notationList);

	}

	OnRefresh();

}
/////////////////////////////////////////////////////////////////////////////

void CAnimSizeDlg::OnSave() 
{
	if (notationList == NULL)
		return;

	if (!notationList->IsChanged())
	{
		return;
	}

	// save current list
	const char *name = NULL;
	if (!notNamed)
	{
		name = notationList->GetFileName();
	}

	CFileDialog dlg(false, ".list", name, OFN_OVERWRITEPROMPT, "Notation List (*.list)|*.list||");

	if (dlg.DoModal() == IDOK)
	{
		//Stuff::FileStream file_stream(dlg.GetPathName(), Stuff::FileStream::WriteOnly);

		notationList->SaveAs(dlg.GetPathName());

		//notationList->Reset();
		Unregister_Object(notationList);
		delete notationList;
		notationList = NULL;

	}

	OnRefresh();

}
/////////////////////////////////////////////////////////////////////////////

void CAnimSizeDlg::OnAddFiles() 
{
	if (notationList == NULL)
	{
		notationList = new NotationFile();
		Register_Object(notationList);

		notNamed = true;
	}

	// add files
	CFileDialog dlg(true, ".mw4anim", NULL, OFN_ALLOWMULTISELECT, "Mech4 Animation (*.mw4anim)|*.mw4anim||");

	char *holder = dlg.m_ofn.lpstrFile;
	
	dlg.m_ofn.lpstrFile = new char [10000];
	Register_Pointer(dlg.m_ofn.lpstrFile);
	dlg.m_ofn.nMaxFile = 10000;

	for (int i = 0; i < 10000; ++i)
	{
		dlg.m_ofn.lpstrFile[i] = NULL;
	}


	Page *page = notationList->SetPage("ANIMLIST");
	Check_Object(page);
	if (dlg.DoModal() == IDOK)
	{
		POSITION pos = dlg.GetStartPosition();
		page->AppendEntry("ANIM", dlg.GetNextPathName(pos));

		while (pos != NULL)
		{
			page->AppendEntry("ANIM", dlg.GetNextPathName(pos));
		}
	}

	Unregister_Pointer(dlg.m_ofn.lpstrFile);
	delete[] dlg.m_ofn.lpstrFile;
	
	dlg.m_ofn.lpstrFile = holder;

	OnRefresh();
}
/////////////////////////////////////////////////////////////////////////////

void CAnimSizeDlg::OnRefresh() 
{

	// clear list

	CListCtrl *list = (CListCtrl *)GetDlgItem( IDC_ANIM_LIST );
	Check_Pointer(list);
	list->DeleteAllItems();

	if (notationList == NULL)
		return;
	
	Page *page = notationList->FindPage("ANIMLIST");
	if (!page)
		return;

	ChainOf<Note*> *anim_name_list = page->MakeNoteChain("ANIM");
	Check_Object(anim_name_list);
	Page::NoteIterator anim_itr(anim_name_list);
	Note *anim_name_entry;

	int count = 0;
	size_t total_size = 0;

	while ((anim_name_entry = anim_itr.ReadAndNext()) != NULL)
	{
		const char *entry_name;
		anim_name_entry->GetEntry(&entry_name);

		AnimListData list_data;
		GetAnimData(entry_name, list_data);


		int icon_image;
		if (list_data.animValid)
		{
			icon_image = 1;
		}
		else
		{
			icon_image = 0;
		}

		int item = list->InsertItem( count, entry_name, icon_image );
		// set other data..

		CString channel_count_text;
		channel_count_text.Format("%d", (int)list_data.channelCount);   

		CString anim_size_text;
		anim_size_text.Format("%d", list_data.animSize);   

		list->SetItemText( item, ColumnArray[CHANNEL_COUNT_COLUMN], channel_count_text );
		list->SetItemText( item, ColumnArray[SIZE_COLUMN], anim_size_text );

		
		total_size += list_data.animSize;
		++count;
	}
	
	Unregister_Object(anim_name_list);
	delete anim_name_list;


	CEdit *edit = (CEdit *)GetDlgItem( IDC_TOTAL_SIZE_EDIT );
	Check_Pointer(edit);


	int total_k = 0;

	if (total_size != 0)
	{
		total_k = total_size / 1024;
	}

	CString size_string;
	size_string.Format("%db / %dk", total_size, total_k);

	edit->SetWindowText( size_string );


}


/////////////////////////////////////////////////////////////////////////////

void CAnimSizeDlg::GetAnimData(const char *name, AnimListData &list_data)
{
	list_data.animValid = false;
	list_data.animSize = 0;
	list_data.channelCount = 0;



	AnimData new_anim;

	if (new_anim.Load(name))
	{
		list_data.animValid = true;

		list_data.animSize = sizeof(new_anim) + new_anim.GetSize();;
		list_data.channelCount = new_anim.GetChannelCount();
	}



}
/////////////////////////////////////////////////////////////////////////////

void CAnimSizeDlg::OnQuit() 
{
	OnClose();

	DestroyWindow( );
}
/////////////////////////////////////////////////////////////////////////////

void CAnimSizeDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	
	if (notationList != NULL)
	{
		OnSave();
		notationList->IgnoreChanges();
		Unregister_Object(notationList);
		delete notationList;
		notationList = NULL;

	}
	CDialog::OnClose();
}

void CAnimSizeDlg::OnButtonDetail() 
{
	CListCtrl *list = (CListCtrl *)GetDlgItem( IDC_ANIM_LIST );
	Check_Pointer(list);


	for (int i = 0; i < list->GetItemCount( ); ++i)
	{
		//if (list->GetCheck(i))
		if (list->GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED)
		{
			AnimData new_anim;
			if (new_anim.Load(list->GetItemText( i, 0) ))
			{
				AnimDetail *new_detail;
				new_detail = new AnimDetail(list->GetItemText( i, 0) );
				new_detail->Create(IDD_ANIMDETAIL_DIALOG);
				new_detail->ShowWindow(SW_SHOW);
			}
		}
	}
}

void CAnimSizeDlg::PostNcDestroy() 
{
	// TODO: Add your specialized code here and/or call the base class
	
	CDialog::PostNcDestroy();

	//delete this;
}
