// File CSpellBook.cpp

#include <afxwin.h>
#include <afx.h>
#include <afxcoll.h>
#include <afxcmn.h>
#include "resource.h"
#include "spell1.h"
#include "CSpellBook.h"
#include "roll.h"
#include "CGroupSpell.h"
#include "main.h"
#include "spellvar.h"
#include "CFormatBook.h"

#define MAX_CASTR	10

/* DA RICORDARE
	spell:
		ADD
		DELETE
	book:
		ADD
		DELETE
		PRINT
		HTML
*/
// mappa dei messaggi
BEGIN_MESSAGE_MAP(CSpellBook, CDialog)
	ON_BN_CLICKED(IDC_VIEWSPELL, OnBtView)
	ON_BN_CLICKED(IDC_STATUS, OnUndoAll)
	ON_BN_CLICKED(IDC_AUTOVIEW, OnAutoView)
	ON_BN_CLICKED(IDC_TORTF, OnFileRTF)
	ON_BN_CLICKED(IDC_TOHTML, OnFileHTML)
	ON_BN_CLICKED(IDC_ADDSPELL, OnButtonAddSpell)
//	ON_BN_CLICKED(IDC_DELETESPELL, OnButtonDeleteSpell)
	ON_WM_DESTROY()
	ON_CBN_SELCHANGE(IDC_BOOKNAME, OnViewBook)
	ON_NOTIFY(TVN_SELCHANGED, IDC_BOOK, OnViewSpellClick )
END_MESSAGE_MAP()

// funzioni membro private

void CSpellBook::LoadListBook(CComboBox *pCBox)
{
	pCBox->ResetContent();

	// ricerca book
	CFileFind trova;
	BOOL found = trova.FindFile("SpellBook\\*.bk");
	while(found)
	{
		found = trova.FindNextFile();
		if (!trova.IsDots() && !trova.IsDirectory())
			pCBox->AddString(trova.GetFileTitle());
	}
}

// scambio dati
int CSpellBook::LoadFileBook(CString name)
{
	// directory predefinita "SpellBook"
	CString nomefile="SpellBook\\";
	nomefile+=name;
	nomefile+=".bk";

	// test per selezione precedente modificata
	if (m_Changed)
		SaveFileBook();

	m_Changed=FALSE;
	((CButton *) GetDlgItem(IDC_STATUS))->SetWindowText("");
	m_CurrBook=name;
	DeleteSpellBook();

	CFile file;
	//apertura del file selezionato.
	if (file.Open(nomefile, CFile::modeRead))
	{
		CArchive ar (&file, CArchive::load);
		m_SpellBook.Serialize(ar);
		ar.Close();
		file.Close();
		return TRUE;
	}
	return FALSE;
}

void CSpellBook::SaveFileBook()
{
	// directory predefinita "SpellBook"
	CString nomefile="SpellBook\\";
	nomefile+=m_CurrBook;
	nomefile+=".bk";

	// test per selezione precedente modificata

	CFile file;
	if (m_Changed)
	{
		//apertura del file selezionato.
		if (file.Open(nomefile, CFile::modeCreate|CFile::modeWrite))
		{
			CArchive ar (&file, CArchive::store);
			m_SpellBook.Serialize(ar);
			ar.Close();
			file.Close();

#ifdef _DEBUG
			CString tmp="File ";
			tmp+=m_CurrBook;
			tmp+=" correttamente salvato!";
			MessageBox(tmp);
#endif

		}
	}
}

void CSpellBook::ViewBook()
{
	HTREEITEM curr_item=TVI_ROOT;
	ListOfSpell()->DeleteAllItems();

	CString curr_caster;
	for (int i=0; i<m_SpellBook.GetSize(); i++)
	{
		CGroupSpell *pGSpell=(CGroupSpell *) m_SpellBook[i];
		if(curr_caster.Compare(pGSpell->m_Caster)!=0)
		{
			curr_caster=pGSpell->m_Caster;
			curr_item=ListOfSpell()->InsertItem(curr_caster, 0, 3);
		}
		HTREEITEM cur_subItem = ListOfSpell()->InsertItem(pGSpell->m_Level, 1, 4, curr_item);
		int num_spell=pGSpell->m_Name.GetSize();
		for (int x=0; x<num_spell; x++)
			ListOfSpell()->InsertItem(pGSpell->m_Name[x], 2, 5, cur_subItem);
	}
}


// dealloca gli elementi dell'array
void CSpellBook::DeleteSpellBook()
{
	for(int i=0; i<m_SpellBook.GetSize(); i++)
		delete m_SpellBook[i];
	m_SpellBook.RemoveAll();
}


// crea un file contenente il book in un formato definito
void CSpellBook::MakeFile(int type)
{
	CString strCurrCaster;
	CStdioFile out_file;
	CFormatBook book;

	// apertura file precedente
	int is_open=0;

	// contatori errori riscontrati
	int num_error=0;

	for(int i=0; i<m_SpellBook.GetSize(); i++)
	{
		CGroupSpell *pGSpell = (CGroupSpell *) m_SpellBook.GetAt(i);

		// creazione file
		if (strCurrCaster.Compare(pGSpell->m_Caster)!=0)
		{
			// definizione nome file e header
			CString nome="Spellbook\\";
			CString header;
			header+=m_CurrBook;
			header+="'s ";
			header+=pGSpell->m_Caster;
			header+="Spellbook";
			nome+=header;
			switch(type)
			{
			case TXT:
				nome+=".txt";
				break;
			case RTF:
				nome+=".rtf";
				break;
			case HTML:
				nome+=".html";
				break;
			}
 
			strCurrCaster=pGSpell->m_Caster;

			if (is_open)
			{
				// chiusura book precedente
				book.End(0);
				out_file.WriteString(book.ReturnString());
				out_file.Close();
			}
			
			// inizializza strutture dati interne
			book.Init(type);
			//crea testata
			book.SetHeader(header);

			if(out_file.Open(nome, CFile::modeWrite|CFile::modeCreate)==NULL)
			{
				MessageBox("Non riesco a generare il file di output!","Errore!");
				return;
			}
			is_open=1;
		} else {
			book.Init(type, RESET_STR);
			book.InsertPage();
		}

		// un elemento contiene tutti i riferimenti ad un caster ed un livello
		book.WriteTitle(pGSpell->m_Level);

		for(int j=0; j<pGSpell->m_Name.GetSize(); j++)
		{
			// leggi il file

			//estrai nome
			CString path;
			path=pGSpell->m_Caster;
			path+="\\";
			path+=pGSpell->m_Level;
			path+="\\";
			path+=pGSpell->m_Name[j];
			path+=".txt";

			CStdioFile ToOpen;
			if(ToOpen.Open(path, CFile::modeRead)==NULL)
			{
				MessageBox("Impossibile leggere l'incantesimo" + pGSpell->m_Name[j], "--Errore!!");
				num_error++;
			}
			else
			{
				CString testo;
				book.Write("",CR);
				book.WriteBolt(pGSpell->m_Name[j],CR);
				ToOpen.ReadString(testo);
				while (ToOpen.ReadString(testo))
				{
					book.Write(testo,CR);
				}
				ToOpen.Close();
			}
		}
		out_file.WriteString(book.ReturnString());
	}
	book.Init(type, RESET_STR);
	book.End(0);
	out_file.WriteString(book.ReturnString());
	out_file.Close();
	if (num_error!=0)
	{
		char tmp[3];
		CString error_str="Creato libro incontesimi\nRiscontrati ";
		error_str+=itoa(num_error, tmp, 10);
		error_str+=" errori!!";
		MessageBox(error_str, "Creazione BOOK");
	} else {
		MessageBox("Creazione book effettuata con successo !!","Book");
	}
}


// funzioni membro pubbliche
CSpellBook::CSpellBook(CWnd *pWnd)
{
	Create(IDD_SPELLBOOK);
	SetIcon(AfxGetApp()->LoadIcon(IDI_ICON4),TRUE);
	SetWindowText("Spell Book Manager");
}

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

	CImageList *pImageList=new CImageList;
	pImageList->Create(16, 16, ILC_COLOR4, 3, 1);
	pImageList->Add(::AfxGetApp()->LoadIcon(IDI_VIEW0));	// caster normal	0
	pImageList->Add(::AfxGetApp()->LoadIcon(IDI_VIEW1));	// level normal		1
	pImageList->Add(::AfxGetApp()->LoadIcon(IDI_VIEW2));	// spell normal		2
	pImageList->Add(::AfxGetApp()->LoadIcon(IDI_VIEW0S));	// caster select	3
	pImageList->Add(::AfxGetApp()->LoadIcon(IDI_VIEW1S));	// level select		4
	pImageList->Add(::AfxGetApp()->LoadIcon(IDI_VIEW2S));	// spell select		5

	ListOfSpell()->SetImageList(pImageList, TVSIL_NORMAL);

	LoadListBook(ListOfBook());
	m_Changed=FALSE;
	return TRUE;
}


void CSpellBook::AddSpell(DEFSPELL dspell)
{
#ifdef _DEBUG
	MessageBox(dspell.Name, dspell.Level);
#endif
	if(m_CurrBook.IsEmpty())
	{
		CSpellBookSelect sel (this);
		while (m_CurrBook.IsEmpty())
		{
			::MessageBeep(MB_OK);
			if(sel.DoModal()==IDOK)
				m_CurrBook=sel.selected;
		}

		if(LoadFileBook(m_CurrBook))
			for (int i=0;i<ListOfBook()->GetCount();i++)
			{
				CString str;
				ListOfBook()->GetLBText(i, str);
				if(str.Compare(m_CurrBook)==0)
				{
					ListOfBook()->SetCurSel(i);
					break;
				}
			}
		else
			ListOfBook()->SetCurSel(ListOfBook()->AddString(m_CurrBook));
	}

	CGroupSpell *pGSpell;
	// posso aver deciso di non selezionare niente
	if(m_CurrBook.IsEmpty())
	{
	} else {
		m_Changed=TRUE;
		((CButton *) GetDlgItem(IDC_STATUS))->SetWindowText("Modified");
		// selezionato nome book
		for (int i=0; i<m_SpellBook.GetSize(); i ++)
		{
			pGSpell=(CGroupSpell *) m_SpellBook[i];
			// verifico se appartiene allínsieme selezionato
			if(dspell.Caster.Compare(pGSpell->m_Caster)==0 && dspell.Level.Compare(pGSpell->m_Level)==0)
			{
				// appartiene all'insieme selezionato
				for (int x=0; x<pGSpell->m_Name.GetSize(); x++)
				{
					if (pGSpell->m_Name[x].Compare(dspell.Name)==0)
					{
						MessageBox("Incantesimo giá presente","AVVISO");
						m_Changed=FALSE;
						ViewBook();
						return;
					}
					if (pGSpell->m_Name[x].Compare(dspell.Name)>0)
						break;
				}

				pGSpell->m_Name.InsertAt(x, dspell.Name);
				ViewBook();
				return;
			} else if (dspell.Caster.Compare(pGSpell->m_Caster)==0 && dspell.Level.Compare(pGSpell->m_Level)<0)
			{
				// appartiene alla stessa scuola
				// ordino rispetto al livello
				break;
			}
		}
		pGSpell = new CGroupSpell;
		pGSpell->m_Caster=dspell.Caster;
		pGSpell->m_Level=dspell.Level;
		pGSpell->m_Name.Add(dspell.Name);
		m_SpellBook.InsertAt(i,pGSpell);
//		delete  pGSpell;
		ViewBook();
	}
}

// funzioni membro protette

void CSpellBook::OnCancel()
{
	DestroyWindow();
}

void CSpellBook::OnDestroy()
{
	if(m_Changed)
		SaveFileBook();

	DeleteSpellBook();
	ListOfSpell()->DeleteAllItems();
	delete ListOfSpell()->GetImageList(TVSIL_NORMAL);
}


void CSpellBook::PostNcDestroy()
{
	((CMainWindow *) AfxGetMainWnd())->m_SpellBook = NULL;
	for (int i=0; i<m_SpellBook.GetSize(); i++)
		delete (CGroupSpell *) m_SpellBook[i];

	delete this;
}

void CSpellBook::OnViewBook()
{
	int pos=ListOfBook()->GetCurSel();
	if (pos!=CB_ERR)
	{
		CString name;
		ListOfBook()->GetLBText(pos, name);
		LoadFileBook(name);
		ViewBook();

		// attivare tasti funzione per BOOK
		((CButton *) GetDlgItem(IDC_TORTF))->EnableWindow();
		((CButton *) GetDlgItem(IDC_TOHTML))->EnableWindow();

		//attivare tasti per funzioni spell
		((CButton *) GetDlgItem(IDC_ADDSPELL))->EnableWindow();
		((CButton *) GetDlgItem(IDC_DELETESPELL))->EnableWindow();
	}
}


void CSpellBook::OnViewSpellClick(NMHDR *pNot, LRESULT *res)
{
	CButton *pBt=(CButton *) GetDlgItem(IDC_AUTOVIEW);

	if (pBt->GetCheck())
	{
		OnBtView();
	}
	else
	{
		// test per selezione incantesimo - attivare tasto View
		if(!ListOfSpell()->GetChildItem(ListOfSpell()->GetSelectedItem()))
		{
			((CButton *) GetDlgItem(IDC_VIEWSPELL))->EnableWindow();
		}
		else
		{
			((CButton *) GetDlgItem(IDC_VIEWSPELL))->EnableWindow(FALSE);
		}
	}
}


void CSpellBook::OnBtView()
{
	if(!ListOfSpell()->GetChildItem(ListOfSpell()->GetSelectedItem()))
	{
		DEFSPELL spell;
		spell.Caster=ListOfSpell()->GetItemText(ListOfSpell()->GetParentItem(ListOfSpell()->GetParentItem(ListOfSpell()->GetSelectedItem())));
		spell.School=0;
//		spell.Level=ListOfSpell()->GetItemText(ListOfSpell()->GetParentItem(ListOfSpell()->GetSelectedItem()));
		spell.Level=ALL;
		spell.Name=ListOfSpell()->GetItemText(ListOfSpell()->GetSelectedItem());

		
		::SendMessage(((CMainWindow*)AfxGetMainWnd())->GetSafeHwnd(), WM_USERBOOKVIEWSPELL, 0, (LPARAM) &spell);
	}
}

void CSpellBook::OnUndoAll()
{
	if (AfxMessageBox("Si desidera ripristinare il libro con le informazioni iniziali ?",MB_YESNO)==IDYES)
	{
		m_Changed=FALSE;
		LoadFileBook(m_CurrBook);
		ViewBook();
	}
}


void CSpellBook::OnAutoView()
{
	if(((CButton *) GetDlgItem(IDC_AUTOVIEW))->GetCheck())
		((CButton *) GetDlgItem(IDC_VIEWSPELL))->EnableWindow(FALSE);
	else
		((CButton *) GetDlgItem(IDC_VIEWSPELL))->EnableWindow();
}

// creazione del file RTF
void CSpellBook::OnFileRTF()
{
	MakeFile(RTF);
}


// creazione del file RTF
void CSpellBook::OnFileHTML()
{
	MakeFile(HTML);
}


// Abilita inserimento spell
void CSpellBook::OnButtonAddSpell()
{
	::SendMessage(((CMainWindow*)AfxGetMainWnd())->GetSafeHwnd(), WM_USERSBOOKTOADD, 0, 0);
}


// definizione membri di CSpellBookSelect

BOOL CSpellBookSelect::OnInitDialog()
{
	CFileFind trova;
	BOOL found = trova.FindFile("SpellBook\\*.bk");
	while(found)
	{
		found = trova.FindNextFile();
		if (!trova.IsDots() && !trova.IsDirectory())
			((CComboBox *) GetDlgItem(IDC_CAST))->AddString(trova.GetFileTitle());
	}

	return TRUE;
}

