// File: Spell1.cpp
// Definizione dei metodi delle classi di spell1.h
#include <afxwin.h>
#include <direct.h>
#include <afxcmn.h>
#include <stdlib.h> //da cancellare
#include "resource.h"
#include "spellvar.h"
#include "roll.h"
#include "spell1.h"
#include "CSpellBook.h"
#include "spell2.h"
#include "main.h"
#include "search.h"

#include "tables.cpp"

#define LIST 0		// Ricerca sul livello impostato
#define DEEP 1		// Ricerca dei file ricorsivamente su + dir

#define IDM_EDIT	1
#define IDM_BOOK	2
#define IDM_ADDBOOK	3
#define IDM_SCHOOL	20

BEGIN_MESSAGE_MAP(CSpellView, CDialog)
	ON_BN_CLICKED(IDC_CLOSE, OnCancel)
	ON_BN_CLICKED(IDC_SEARCH, OnSearch)
	ON_BN_CLICKED(IDC_GLOBALVIEW, OnGlobalView)
	ON_CBN_SELCHANGE(IDC_S_TYPE, OnCasterSet)
	ON_CBN_SELCHANGE(IDC_S_LEVEL, OnLevelSet)
	ON_CBN_SELCHANGE(IDC_S_SCHOOL, OnSchoolSet)
	ON_CBN_SELCHANGE(IDC_S_NAME, OnNameSet)
	ON_WM_CONTEXTMENU()
	ON_WM_SYSCOMMAND()
	ON_MESSAGE(WM_USERSPELL, OnViewSpell1)
END_MESSAGE_MAP()

// Definizione funzioni membro pubbliche

CSpellView::CSpellView(int mode)
{
	m_iMode=mode;
	if(!m_iMode)
		Create(IDD_SPELL_SPELL);
	else
		Create(IDD_SPELL_SPELL_TOADD);
	SetIcon(AfxGetApp()->LoadIcon(IDI_ICON3),TRUE);
	SetWindowText("Spell View");
}

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

		m_Caster=NOVALUE;
		m_Level=NOVALUE;
		m_School=NOTINIT;
		m_Spell=NOVALUE;
		m_OldSearchCaster="";
		m_pgvd=NULL;

		CInitSpell myFile;
		if(!myFile.InitStruct(m_CasterName, m_SchoolName))
		{
				SendMessage(WM_CLOSE);
				return FALSE;
		}
	if(!m_iMode)
	{
		for (int cont=0; cont < m_CasterName.GetSize(); cont++)
			CasterType().AddString(m_CasterName[cont]);
	} else {
		OnGlobalView();
	}
	return TRUE;
}


// Definizione funzioni membro private
void CSpellView::SetLevelSpell()
{
	if (m_Caster==NOVALUE)
		return;
	CString str=m_Caster+"\\*.*";
	LevelSpell().ResetContent();
	DirFullName(&LevelSpell(), (LPCTSTR)str, LIST, NOSEARCH);
	LevelSpell().SetCurSel(LevelSpell().AddString(ALL));
	m_Level=ALL;
	SetNameSpell();
}

void CSpellView::SetSchoolSpell()
{
	if (m_Caster==NOVALUE)
		return;
	SchoolSpell().ResetContent();
	CStringArray * CSAptr = m_SchoolName.GetTable(WhoCast(), 0);
	int maxschool= CSAptr->GetSize();
	for (int cont=0;cont<maxschool;cont++)
		SchoolSpell().AddString(CSAptr->GetAt(cont));
	SchoolSpell().SetCurSel(SchoolSpell().AddString(ALL));
	m_School=NONE;
	SetNameSpell();
}

void CSpellView::SetNameSpell()
{
	if (m_Caster==NOVALUE || m_Level==NOVALUE || m_School==NOTINIT)
		return;

	AfxGetApp()->DoWaitCursor(1);
	NameSpell().ResetContent();
	if(m_School==NONE)
	{
		CString dirview=m_Caster;
		if (m_Level==ALL)
			dirview+="\\*.*";
		else
			dirview+="\\"+m_Level+"\\*.*";
		DirFullName(&NameSpell(), (LPCTSTR) dirview, DEEP, NOSEARCH);
	}
	else
	{
		CString dirview=m_Caster;
		if (m_Level==ALL)
			dirview+="\\*.*";
		else
			dirview+="\\"+m_Level+"\\*.*";
		DirFullName(&NameSpell(), (LPCTSTR)dirview, DEEP, SEARCH);
	}
	CString descrizione;
	descrizione.Format("Spell View - %d spell found",NameSpell().GetCount());
	SetWindowText((LPCTSTR) descrizione);
	AfxGetApp()->DoWaitCursor(-1);
}

// locazione deve essere un percorso che termina con *.*
void CSpellView::DirFullName(CComboBox *lista, const char * locazione, int scansione, int ricerca)
{
    CFileFind trova;
    BOOL found = trova.FindFile(locazione);
    while (found)
    {
        found = trova.FindNextFile();
		if (!trova.IsDots())
		{
			if(trova.IsDirectory()&&scansione==DEEP) // Ricerca in profonditá
			{
				CString newdir = locazione;
				newdir=newdir.Left(newdir.GetLength()-3);		// locazione contiene sempre ...\\*.*
				newdir+=trova.GetFileName()+"\\*.*";
				DirFullName(lista, (LPCTSTR)newdir, DEEP, ricerca);
			}
			else
			if (ricerca==NOSEARCH || trova.IsDirectory()) // Scuola generica e x directori in caso di ricerca
			{
				CString tmp = trova.GetFileName();
				int pos = tmp.Find('.');
				if (pos!=-1)
					tmp=tmp.Left(pos);
				lista->AddString((LPCTSTR) tmp);
			}
			else
			{
				CString filetoopen=locazione;
				filetoopen=filetoopen.Left(filetoopen.GetLength()-3);
				filetoopen+= trova.GetFileName();
				CStdioFile spellfile ((LPCTSTR) filetoopen, CFile::modeRead);
				CString schoolofspell;
				spellfile.ReadString(schoolofspell);
				spellfile.ReadString(schoolofspell);	// posiziona alla seconda riga.

				// estrazione stringa di riferimento scuola wizard o caster pura (priest es.)
				if(m_Caster!="Wizard")
					if (AfxGetApp()->GetProfileInt("Options",m_Caster,0))
					{
						// come wizard
						int pos_sep=schoolofspell.Find(")(");
						schoolofspell=schoolofspell.Left(pos_sep);
					} else {
						//scuola nativa
						int pos_sep=schoolofspell.Find(")(");
						schoolofspell=schoolofspell.Mid(pos_sep+1);
					}


				// valutazione nelle lingue del DB
				int isinlist = NO;
				int cont = 0;
				int lingue=m_SchoolName.GetColumn();
				while (cont < lingue && isinlist==NO)
				{
					m_SchoolName.SetTable(WhoCast(), cont);
					cont++;
					CString tmp=m_SchoolName.GetItem(m_School);
					int pos=tmp.Find('/');
					if (pos>0)
						tmp=tmp.Left(pos);
					isinlist=schoolofspell.Find(tmp);
				}

				// patch per global spell
				if (isinlist==NO)
					isinlist=schoolofspell.Find("All");
				if (isinlist==NO)
					isinlist=schoolofspell.Find("Tutte");

				if (isinlist!=NO)
					lista->AddString(trova.GetFileTitle());
			}
		}
    }
}

void CSpellView::DisplaySpell()
{
	CString filename;
	CheckName(filename);

	if (m_Caster== NOVALUE || m_Level==NOVALUE || m_School==NOTINIT || m_Spell==NOVALUE)
		return;

	CStdioFile openfile ((LPCTSTR) filename, CFile::modeRead);

	// Inizializzazione dati incantesimo
	CString descrizione;
	openfile.ReadString(descrizione);			// Nome Spell
	SetTitleBar(descrizione, filename);

	openfile.ReadString(descrizione);			// Scuola
	ViewSchool(descrizione);

	openfile.ReadString(descrizione);			// Reversibile
	BOOL value=FALSE;
	if (descrizione.Find("Reversible") !=-1 || descrizione.Find("Reversibile")!= -1)  //da modificare
	{
		value=TRUE;
		openfile.ReadString(descrizione);		// elimina lo spazio dopo reversible
	}
	TextSpell(REVERT).EnableWindow(value);

	openfile.ReadString(descrizione);			// Range
	TextSpell(RANGE).SetWindowText(descrizione);

	openfile.ReadString(descrizione);			// Component
	TextSpell(COMPONENT).SetWindowText(descrizione);

	openfile.ReadString(descrizione);			// Durata
	TextSpell(DURATA).SetWindowText(descrizione);

	openfile.ReadString(descrizione);			// Casting time
	TextSpell(CASTING).SetWindowText(descrizione);

	openfile.ReadString(descrizione);			// Area of Effect
	TextSpell(AREAEFFECT).SetWindowText(descrizione);

	openfile.ReadString(descrizione);			// Saving Throw
	TextSpell(SAVING).SetWindowText(descrizione);
	openfile.ReadString(descrizione);

	// Descrizione incantesimo
	CString spelldescr;
	while (openfile.ReadString(descrizione))
		spelldescr+=descrizione+"\r\n";
	EditSpell().SetWindowText(spelldescr);
}

void CSpellView::SetTitleBar(CString descrizione, CString percorso)
{
	CString titolo="Spell View - ";
	if(m_Level==ALL)
	{
//		CString percorso;
//		CSearchDir sdir;
//		percorso=sdir.GetDir(m_Caster, descrizione+".txt", m_Caster);
		percorso=percorso.Right(percorso.GetLength()-percorso.Find("\\")-1);
		percorso=percorso.Left(percorso.Find("\\"));
		titolo+= percorso + " - ";
		m_LevelNotAll=percorso;
	}
	titolo+= descrizione;
	SetWindowText((LPCTSTR) titolo);
}

int CSpellView::WhoCast()
{
	if (m_Caster==NOVALUE)
		return -1;
	if (AfxGetApp()->GetProfileInt("Options",m_Caster,0))
		return 0;

	for (int cont=0; cont<m_CasterName.GetSize(); cont++)
		if (m_Caster==m_CasterName[cont])
			return cont;
	return -1;
}

void CSpellView::CheckName(CString &percorso)
{
	if (m_Caster== NOVALUE || m_Level==NOVALUE || m_School==NOTINIT || m_Spell==NOVALUE)
		return;

	if (m_Level==ALL)
	{
		CSearchDir nome;
		percorso= nome.GetDir(m_Caster, m_Spell+".txt", m_Caster);
		if (percorso.GetLength()==0)
		{
			m_Spell=NOVALUE;
			NameSpell().ResetContent();
		}
	}
	else
	{
		percorso=m_Caster;
		percorso+="\\"+m_Level;
		percorso+="\\"+m_Spell+".txt";
	}
}

void CSpellView::ViewSchool(CString descrizione)
{
	if(m_Caster!="Wizard" && !(AfxGetApp()->GetProfileInt("Options",m_Caster,0)))
	{
		int pos=descrizione.Find(")(");
		descrizione=descrizione.Mid(pos+1);
	}
	descrizione=descrizione.SpanExcluding(")");
	descrizione=descrizione.Mid(1+descrizione.Find('('));
	descrizione="School :   "+descrizione;
	TextSpell(SCHOOL).SetWindowText(descrizione);
}

// Definizione funzioni membro protette

void CSpellView::OnCancel()
{
	if(m_pgvd)
		m_pgvd->OnCancel();
	DestroyWindow();
}

void CSpellView::OnCasterSet()
{
	int pos=CasterType().GetCurSel();
	if(pos<0)
		return;
	CasterType().GetLBText(pos, m_Caster);
	SetLevelSpell();
	SetSchoolSpell();
	LevelSpell().EnableWindow();
	SchoolSpell().EnableWindow();
	NameSpell().EnableWindow();
	ViewButton().EnableWindow();
}

void CSpellView::OnLevelSet()
{
	if (m_Caster==NOVALUE)
		return;
	LevelSpell().GetLBText(LevelSpell().GetCurSel(), m_Level);
	SetNameSpell();
}

void CSpellView::OnSchoolSet()
{
	if (m_Caster==NOVALUE)
		return;
	CString tmp;
	SchoolSpell().GetLBText(SchoolSpell().GetCurSel(), tmp);
	if (tmp==ALL)
		m_School=NONE;
	else
	{
		int cont=0;
		CStringArray * CSAptr=m_SchoolName.GetTable(WhoCast(), 0);
		int maxschool=CSAptr->GetSize();
		while (cont < maxschool)
		{
			if (tmp.Find(CSAptr->GetAt(cont))!=-1)
				break;
			cont++;
		}
		if (cont < maxschool)
			m_School=cont;
		else
		{
			m_School=NONE;
			MessageBox("ERRORE: assegnamento non in relazione con il Data Base.","MESSAGGIO DI ERRORE");
		}
	}
	SetNameSpell();
}

void CSpellView::OnNameSet()
{
	if (m_Caster==NOVALUE || m_Level==NOVALUE || m_School==NOTINIT)
		return;
	int pos=NameSpell().GetCurSel();
	if(pos<0)
		return;
	NameSpell().GetLBText(pos, m_Spell);
	m_Spell.TrimRight();
	
	DisplaySpell();
}

void CSpellView::OnContextMenu(CWnd * pCWnd, CPoint punto)
{
	CRect rect;
	GetClientRect(&rect);
	ClientToScreen(&rect);
	if (!m_iMode && rect.PtInRect(punto))
	{
		int cont=0;
		CMenu menu;
		menu.CreatePopupMenu();
		if(m_CasterName[cont]=="Wizard")
			cont++;
		for(;cont<m_CasterName.GetSize();cont++)
		{
			UINT flag=MF_ENABLED|MF_STRING|(AfxGetApp()->GetProfileInt("Options",m_CasterName[cont],0)?MF_CHECKED:0);
			CString label= m_CasterName[cont]+" school as Wizard school";
			menu.AppendMenu(flag, IDM_SCHOOL+cont, label);
		}
		menu.AppendMenu(MF_SEPARATOR);
		menu.AppendMenu(MF_ENABLED|MF_STRING, IDC_SEARCH, "Search Spell...");
		menu.AppendMenu(MF_ENABLED|MF_STRING, IDC_GLOBALVIEW, "View all spell...");
		menu.AppendMenu(MF_ENABLED|MF_STRING, IDM_ADDBOOK, "Add this to current book");
		menu.AppendMenu(MF_GRAYED|MF_STRING, IDM_BOOK, "Make a spellbook...");
		menu.AppendMenu(MF_GRAYED|MF_STRING, IDM_EDIT, "Edit a spell...");

		int id=(int) menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_RETURNCMD, punto.x, punto.y, this);

		if (id)
			SendMessage(WM_SYSCOMMAND, id, 0);
	}
	else
		CWnd::OnContextMenu(pCWnd, punto);
}

void CSpellView::OnSysCommand(UINT nID, LPARAM lparam)
{
	int cast=nID-IDM_SCHOOL;
	if ( cast>=0 && cast<m_CasterName.GetSize() )
	{
		if (m_CasterName[cast]=="Wizard")
			MessageBox("Wizard don't appair in this selections!","SYSTEM ERROR");
		else
		{
			int oldstatus=AfxGetApp()->GetProfileInt("Options",m_CasterName[cast],0);
			AfxGetApp()->WriteProfileInt("Options",m_CasterName[cast],oldstatus?0:1);
			SetSchoolSpell();
		}
		return;
	}
	// definizione variabile per comunicazione tra windows
	DEFSPELL tospell;
	switch(nID)
	{
	case IDC_SEARCH:
		OnSearch();
		break;
	case IDC_GLOBALVIEW:
		OnGlobalView();
		break;
	case IDM_EDIT:
		break;
	case IDM_BOOK:
		break;
	case IDM_ADDBOOK:
	if (m_Caster== NOVALUE || m_Level==NOVALUE || m_School==NOTINIT || m_Spell==NOVALUE)
		return;
		tospell.Caster=m_Caster;

		if (m_Level.Compare(ALL)==0)
			tospell.Level=m_LevelNotAll;
		else
			tospell.Level=m_Level;

		tospell.Name=m_Spell;
		::SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_USERADDBOOK,0,(LPARAM) & tospell);
		break;
	default : CWnd::OnSysCommand(nID, lparam);
	}
}

void CSpellView::OnSearch()
{
	CSearchDialog searchdial;
	searchdial.m_FirstPage.m_CasterName=&m_CasterName;
	searchdial.m_FirstPage.m_SchoolName=&m_SchoolName;
	if(!m_OldSearchCaster.IsEmpty())
	{
		searchdial.m_FirstPage.m_CasterSel=m_OldSearchCaster;
		searchdial.m_FirstPage.m_SchoolSel=&m_OldSearchSchool;
		searchdial.m_FirstPage.m_LevelSel=&m_OldSearchLevel;
	}
	if(searchdial.DoModal()==IDOK)
	{
		if(!searchdial.m_FirstPage.m_CasterSel.IsEmpty())
		{
			m_OldSearchCaster=searchdial.m_FirstPage.m_CasterSel;
			m_OldSearchSchool=&searchdial.m_FirstPage.m_SchoolSel;
			m_OldSearchLevel=&searchdial.m_FirstPage.m_LevelSel;
			if(!searchdial.m_ThirdPage.m_NameSel.IsEmpty())
			{
				m_Caster=m_OldSearchCaster;
				m_Level=ALL;
				m_School=0;
				m_Spell=searchdial.m_ThirdPage.m_NameSel;

				LevelSpell().ResetContent();
				LevelSpell().EnableWindow(FALSE);
				SchoolSpell().ResetContent();
				SchoolSpell().EnableWindow(FALSE);
				NameSpell().ResetContent();
				NameSpell().SetCurSel(NameSpell().AddString(m_Spell));
				CasterType().SetCurSel(CasterType().FindString(-1, searchdial.m_FirstPage.m_CasterSel));

				DisplaySpell();
			}
			else
			{
				int num=searchdial.m_ThirdPage.m_AllName.GetSize();
				if(num)
				{
					m_Caster=m_OldSearchCaster;
					m_Level=ALL;
					m_School=0;

					LevelSpell().ResetContent();
					LevelSpell().EnableWindow(FALSE);
					SchoolSpell().ResetContent();
					SchoolSpell().EnableWindow(FALSE);
					NameSpell().ResetContent();
					NameSpell().EnableWindow();
					CasterType().SetCurSel(CasterType().FindString(-1, searchdial.m_FirstPage.m_CasterSel));

					for(int cont=0; cont<num; cont++)
						NameSpell().AddString(searchdial.m_ThirdPage.m_AllName.GetAt(cont));
				}
			}
		}
	}
}

void CSpellView::OnGlobalView()
{
	if(m_pgvd==NULL)
	{
		m_pgvd=new CGlobalViewDialog(SPELL, this);
		m_pgvd->SetTree(m_CasterName);
		CasterType().SetCurSel(-1);
		CasterType().EnableWindow(FALSE);
		LevelSpell().ResetContent();
		LevelSpell().EnableWindow(FALSE);
		SchoolSpell().ResetContent();
		SchoolSpell().EnableWindow(FALSE);
		NameSpell().EnableWindow(FALSE);
	}

	m_pgvd->ShowWindow(SW_SHOW);
}

void CSpellView::OnViewSpell1(UINT wparam, long lparam)
{
	DEFSPELL *pDef=(DEFSPELL*) lparam;
	m_Caster=pDef->Caster;
	m_Level=pDef->Level;
	m_School=pDef->School;
	m_Spell=pDef->Name;
	CasterType().SetCurSel(CasterType().FindString(-1, m_Caster));

	NameSpell().ResetContent();
	NameSpell().AddString(m_Spell);
	NameSpell().SetCurSel(0);

	DisplaySpell();
}

void CSpellView::PostNcDestroy()
{
	((CMainWindow *) AfxGetMainWnd())->m_Spell = NULL;
	delete this;
}