// DisperseDlg.cpp : implementation file
//

#include "stdafx.h"
#include "mw4gameed2.h"
#include "DisperseDlg.h"
#include "ObjectManager.h"
#include "UndoManager.h"
#include "DisperProg.h"
#include "ObjCreateInfo.h"
#include <ImageLib\Image.h>
#include <GameOS\ToolOS.hpp>
#include <MW4\MW4.hpp>

/////////////////////////////////////////////////////////////////////////////
// CDisperseDlg dialog


CDisperseDlg::CDisperseDlg(ObjectManager *oman,CWnd* pParent /*=NULL*/)
: CDialog(CDisperseDlg::IDD, pParent)
{
	ObjMan=oman;
	
	//{{AFX_DATA_INIT(CDisperseDlg)
	m_BmpPath = _T("");
	//}}AFX_DATA_INIT
}


void CDisperseDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDisperseDlg)
	DDX_Control(pDX, IDC_RESOURCELIST, m_RList);
	DDX_Control(pDX, IDC_TYPETAB, m_TTab);
	DDX_Control(pDX, IDC_OBJLIST, m_ObjList);
	DDX_Text(pDX, IDC_BMPPATH, m_BmpPath);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDisperseDlg, CDialog)
//{{AFX_MSG_MAP(CDisperseDlg)
ON_BN_CLICKED(IDC_ADDOBJ, OnAddobj)
ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
ON_BN_CLICKED(IDC_DELOBJ, OnDelobj)
ON_WM_CLOSE()
ON_NOTIFY(TCN_SELCHANGE, IDC_TYPETAB, OnSelchangeTypetab)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDisperseDlg message handlers

void CDisperseDlg::OnAddobj() 
{
	// TODO: Add your control notification handler code here
	int scount=m_RList.GetSelCount();
	if(scount<=0) return;
	int *selitms=new int[scount];
	m_RList.GetSelItems(scount,selitms);
	
	int i;
	for(i=0;i<scount;i++)
	{
		ObjCreateInfo *inf=new ObjCreateInfo;
		*inf=*((ObjCreateInfo *)m_RList.GetItemData(selitms[i]));
		int itm;
		itm=m_ObjList.AddString(inf->Path);
		m_ObjList.SetItemDataPtr(itm,inf);
	}
	
	
	delete selitms;
}


void CDisperseDlg::OnBrowse() 
{
	UpdateData(TRUE);
	CFileDialog fdlg(TRUE,NULL,NULL,OFN_NOCHANGEDIR,"Bitmap Images (*.tif,*.gif,*.tga)|*.tif;*.gif;*.tga||",this);
	
	if(fdlg.DoModal()==IDOK)
	{
		m_BmpPath=fdlg.GetPathName();
		UpdateData(FALSE);
	}
}

void CDisperseDlg::OnOK() 
{
	
	int i,objlcount=m_ObjList.GetCount();
	// TODO: Add extra validation here
	if(m_BmpPath=="" || !gos_DoesFileExist(m_BmpPath)) 
	{
		MessageBox("Cannot Load Bmp File","Dispersial Error",MB_OK);
		return;
	}
	
	if(objlcount<=0) 
	{
		MessageBox("No Objects to Disperse","Dispersial Error",MB_OK);
		return;
	}
	
	Image img;
	img.Load((char *)(LPCSTR)m_BmpPath);
	img.Rotate180();
	if(img.GetBpp()>8) img.ReduceTo8Bit(RMD_MAX);
	BYTE *dat=img.Lock();
	int x,y;
	DWORD show_flag=0;
	
	float gridxsize,gridzsize;
	
	ObjCreateInfo **PList;
	PList=new ObjCreateInfo *[objlcount];
	for(i=0;i<objlcount;i++) PList[i]=(ObjCreateInfo *)m_ObjList.GetItemDataPtr(i);
	
	
	int total=img.GetHeight()*img.GetWidth();
	int current=0;
	Point3D MapSize;
	MapSize=ObjMan->GetMapSize();
	
	gridxsize=MapSize.x/img.GetWidth();
	gridzsize=MapSize.z/img.GetHeight();
	
	ObjMan->ClearSelection();
	
	AddCommand *com=NULL;
	AddCommand *lcom=NULL;
	int objtot=0;
	for(y=0;y<img.GetHeight();y++)
		for(x=0;x<img.GetWidth();x++)
			if(dat[x+img.GetPitch()*y])
			{
				objtot++;
			}
			CDisperProg dlg(this);
			
			dlg.SetTot(objtot);
			int pcount=0;
			for(y=0;y<img.GetHeight();y++)
				for(x=0;x<img.GetWidth();x++)
				{
					current++;
					if(dat[x+img.GetPitch()*y])
					{
						Point3D pos;
						YawPitchRoll rot;
						Stuff::LinearMatrix4D mat;
						EdGUIObject *gobj;
						pos.x=(x*gridxsize+Stuff::Random::GetFraction()*gridxsize)-MapSize.x*0.5f;
						pos.z=(y*gridzsize+Stuff::Random::GetFraction()*gridzsize)-MapSize.z*0.5f;
						pos.y=0.0f;
						
						rot.yaw=Stuff::Random::GetFraction()*Two_Pi;
						rot.pitch=0.0f;
						rot.roll=0.0f;
						
						int objidx;
						objidx=(rand()*objlcount)/RAND_MAX;
						Verify(objidx<objlcount);
						gobj=ObjMan->AddAt(PList[objidx],&lcom,&show_flag,false,pos,rot);
						if(gobj!=NULL)
						{
							
							if(com==NULL && lcom) com=lcom;
							lcom=(AddCommand *)lcom->GetLastLink();
							gobj->Select();
							
							while(gobj->IsMultiTile())
							{
								
								dlg.Misplace();
								
								pos.x=(x*gridxsize+Stuff::Random::GetFraction()*gridxsize)-MapSize.x*0.5f;
								pos.z=(y*gridzsize+Stuff::Random::GetFraction()*gridzsize)-MapSize.z*0.5f;
								pos.y=0.0f;
								
								rot.yaw=Stuff::Random::GetFraction()*Two_Pi;
								rot.pitch=0.0f;
								rot.roll=0.0f;
								
								mat.BuildRotation(rot);
								mat.BuildTranslation(pos);
								
								gobj->SetMat(mat);
								
								
							}
							pcount++;
							if(pcount>=10) {dlg.Place(pcount); pcount=0;}
						}
						
					}
				}
				img.UnLock();
				
				if(com)
					ObjMan->SaveUndoCommand(com);
				
				CDialog::OnOK();
				delete PList;
				
				
				
}


void CDisperseDlg::OnDelobj() 
{
	int sel=m_ObjList.GetCurSel();
	if(sel>=0)
	{
		delete (ObjCreateInfo *)m_ObjList.GetItemDataPtr(sel);
		m_ObjList.DeleteString(sel);
	}	
}


void CDisperseDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	int i;
	for(i=0;i<m_ObjList.GetCount();i++)
	{
		delete (ObjCreateInfo *)m_ObjList.GetItemDataPtr(i);
	}
	
	for(i=0;i<m_RList.GetCount();i++) 
	{
		ObjCreateInfo *inf=(ObjCreateInfo *)m_RList.GetItemData(i);
		if(inf) delete inf;
	}
	
	CDialog::OnClose();
}

BOOL CDisperseDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	int idx=0;
	MechList=m_TTab.InsertItem(idx++,"Mechs");
	BuildList=m_TTab.InsertItem(idx++,"Buildings");
	VehList=m_TTab.InsertItem(idx++,"Vehicles");
	LightList=m_TTab.InsertItem(idx++,"Lights");
	CultList=m_TTab.InsertItem(idx++,"Culturals");
	MiscList=m_TTab.InsertItem(idx++,"Misc");
	GetGameData();
	
	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

void CDisperseDlg::GetGameData()
{
	
	if(Adept::ResourceManager::Instance==NULL) return;
	Adept::Resource curres;
	curres.First(NULL);
	
	
	CString res_name,base_name,dir_name;
	int item,tabsel;
	tabsel=m_TTab.GetCurSel();
	int depth,sp,i;
	
	for(i=0;i<m_RList.GetCount();i++) 
	{
		ObjCreateInfo *inf=(ObjCreateInfo *)m_RList.GetItemData(i);
		if(inf) delete inf;
	}
	
	m_RList.ResetContent();
	
	while(curres.ReadAndNext())
	{
		res_name=(char *)curres.GetName();
		res_name.MakeLower();
		
		if(res_name.Right(9).Compare(".instance")==NULL)
		{									// This is a Data File
			base_name=res_name.Mid(res_name.ReverseFind('\\')+1);
			base_name=base_name.Left(base_name.GetLength()-9);
			
			if(base_name.CompareNoCase("Interface"))
			{
				if(tabsel==BuildList)
					sp=res_name.Find("buildings\\");
				else if(tabsel==VehList) 
					sp=res_name.Find("vehicles\\");
				else if(tabsel==MechList)  
					sp=res_name.Find("mechs\\"); 
				else if(tabsel==CultList)  
					sp=res_name.Find("culturals\\"); 
				else if(tabsel==MiscList)  
					sp=res_name.Find("misc\\"); 

				depth=0;
				if(sp>=0)
					for(i=sp;i<res_name.GetLength();i++) 
						if(res_name[i]=='\\') 
							depth++;	// Count Tree Depth	
						
						if( sp!=-1 &&
							(res_name.Find("transpork")<0)
							&&(
							(tabsel==BuildList && depth==2) ||
							(tabsel==VehList   && depth==2) ||
							(tabsel==MechList  && depth==2) || 
							(tabsel==CultList  && depth==2) )
							)
						{
							item=m_RList.AddString(base_name);
							ObjCreateInfo *inf=new ObjCreateInfo;
							inf->CreateType=ObjCreateInfo::OT_GAMEOBJ;
							inf->Path=res_name;
							m_RList.SetItemData(item,(unsigned long)inf);
						}
			
							if( sp!=-1 && tabsel==MiscList  && depth==2 && 
								base_name.CompareNoCase("path") && 
								base_name.CompareNoCase("objective") 
								) 
							{ 
								item=m_RList.AddString(base_name);
								ObjCreateInfo *inf=new ObjCreateInfo;
								inf->Path=res_name;
								
								if(!base_name.CompareNoCase("dropzone"))
								{
									inf->CreateType=ObjCreateInfo::OT_DROPZONE;
								}
								else if(!base_name.CompareNoCase("cameraship"))
								{					
									inf->CreateType=ObjCreateInfo::OT_CAMERA;
								}
								else if(!base_name.CompareNoCase("navpoint"))
								{					
									inf->CreateType=ObjCreateInfo::OT_NVGAMEOBJ;
								}
								else if(!base_name.CompareNoCase("objective"))
								{					
								}
								else if(!base_name.CompareNoCase("fxgenerator"))
								{					
									inf->CreateType=ObjCreateInfo::OT_FX;
								}
								
								m_RList.SetItemData(item,(unsigned long)inf);
							}

			}	
		}
	}
	
	if(tabsel==MiscList)  
	{
		ObjCreateInfo *inf;
		item=m_RList.AddString("Clipboard Contents");
		inf=new ObjCreateInfo;
		inf->CreateType=ObjCreateInfo::OT_CLIPBOARD;
		inf->Path="Cilpboard Contents";
		m_RList.SetItemData(item,(unsigned long)inf);
		
	}

	m_RList.SetCurSel(0);
}

void CDisperseDlg::OnSelchangeTypetab(NMHDR* pNMHDR, LRESULT* pResult) 
{
	GetGameData();	
	*pResult = 0;
}
