// ObjListView.cpp : implementation file
//

#include "stdafx.h"
#include "mw4gameed2.h"
#include "ObjListView.h"
#include "ObjTreeView.h"
#include "GUIObjectList.h"
#include "ObjectManager.h"
#include "UndoManager.h"
#include "Refresher.h"


/////////////////////////////////////////////////////////////////////////////
// CObjListView

IMPLEMENT_DYNCREATE(CObjListView, CView)

CObjListView::CObjListView():DropTarget(this)
{
	ObjMan=NULL;
	MyList=NULL;	

}

CObjListView::~CObjListView()
{
}


BEGIN_MESSAGE_MAP(CObjListView, CView)
//{{AFX_MSG_MAP(CObjListView)
ON_WM_CREATE()
ON_WM_SIZE()
	ON_WM_CHAR()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CObjListView drawing

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

/////////////////////////////////////////////////////////////////////////////
// CObjListView diagnostics

#ifdef _DEBUG
void CObjListView::AssertValid() const
{
	CView::AssertValid();
}

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

/////////////////////////////////////////////////////////////////////////////
// CObjListView message handlers
void CObjListView::Refresh(GUIObjectList *objman)
{
MyList=objman;	
	m_List.DeleteAllItems();

	//Delete the Columns
m_List.DeleteAllColumns();

LVCOLUMN lvc;
ZeroMemory(&lvc,sizeof(lvc));
lvc.mask=LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH; 


	DWORD tagflag=ObjMan->GetTagFlags();
	int nextcol=0;
lvc.cx=150; 
lvc.pszText="Name"; lvc.iSubItem=0; m_List.InsertColumn(nextcol++,&lvc);

lvc.cx=100;
	// Always name

	if(tagflag&TAG_TYPE)			{ lvc.pszText="Type"; lvc.iSubItem=TAGI_TYPE; m_List.InsertColumn(nextcol++,&lvc); m_List.SetColID(nextcol-1,lvc.iSubItem); }
	if(tagflag&TAG_ALIGNMENT)		{ lvc.pszText="Alignment"; lvc.iSubItem=TAGI_ALIGNMENT; m_List.InsertColumn(nextcol++,&lvc); m_List.SetColID(nextcol-1,lvc.iSubItem); }
	if(tagflag&TAG_AINAME)			{ lvc.pszText="AI Name"; lvc.iSubItem=TAGI_AINAME; m_List.InsertColumn(nextcol++,&lvc); m_List.SetColID(nextcol-1,lvc.iSubItem); }
	if(tagflag&TAG_AITYPE)			{ lvc.pszText="AI Type"; lvc.iSubItem=TAGI_AITYPE; m_List.InsertColumn(nextcol++,&lvc); m_List.SetColID(nextcol-1,lvc.iSubItem);}
	if(tagflag&TAG_HOVER_ELEVATION) { lvc.pszText="Hover Elevation"; lvc.iSubItem=TAGI_HOVER_ELEVATION; m_List.InsertColumn(nextcol++,&lvc); m_List.SetColID(nextcol-1,lvc.iSubItem);}
	if(tagflag&TAG_SKINTYPE)		{ lvc.pszText="Skin Type"; lvc.iSubItem=TAGI_SKINTYPE; m_List.InsertColumn(nextcol++,&lvc); m_List.SetColID(nextcol-1,lvc.iSubItem);}
	if(tagflag&TAG_MODIFIED)		{ lvc.pszText="Modified"; lvc.iSubItem=TAGI_MODIFIED; m_List.InsertColumn(nextcol++,&lvc); m_List.SetColID(nextcol-1,lvc.iSubItem);}
	if(tagflag&TAG_SCRIPT)			{ lvc.pszText="Script"; lvc.iSubItem=TAGI_SCRIPT; m_List.InsertColumn(nextcol++,&lvc); m_List.SetColID(nextcol-1,lvc.iSubItem); }


	if(objman!=NULL)
	{
		for(int i=0;i<objman->GetObjectCount();i++)
			objman->GetObject(i)->AddToList(&m_List,tagflag);
	}
	
}

int CObjListView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	m_List.Create(WS_CHILD|LVS_EDITLABELS|LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SHAREIMAGELISTS,CRect(0,0,200,200),this,NULL);
	m_List.ShowWindow(SW_SHOW);
	
	
	DropTarget.Register(&m_List);

	return 0;
}

void CObjListView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	if(GetSafeHwnd()!=NULL)
	{
		m_List.SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER);
	}
	
}

void CObjListView::SetImageList(CImageList *ilist)
{
	m_List.SetImageList(ilist,LVSIL_SMALL);
}

BOOL CObjListView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
{
	HRESULT res=CView::OnNotify(wParam, lParam, pResult);
	NMHDR *hdr=(NMHDR *)lParam;
	
	switch(hdr->code)
	{
	case LVN_ENDLABELEDIT:
		{
			NMLVDISPINFO* pTVDispInfo = (NMLVDISPINFO*)hdr;
			
			EdGUIObject *gobj=(EdGUIObject *)pTVDispInfo->item.lParam;
			
			CString newname=CString(pTVDispInfo->item.pszText);
			if(newname!="")
				ObjMan->SetObjectName(gobj,newname);
			
			
			m_List.SetItemText(pTVDispInfo->item.iItem,pTVDispInfo->item.iSubItem,gobj->GetName());
			Refresher::Instance->OverviewRefresh();
		}
		break;
		
	case LVN_MARQUEEBEGIN: 
		{
		}
		break;
	case LVN_ITEMCHANGED: 
		{
			NMLISTVIEW* idat = (NMLISTVIEW*)hdr;
			if(GetFocus()==&m_List && idat->uChanged&LVIF_STATE)
			{
				UpdateDataSel();
				Refresher::Instance->OverviewRefresh();
			}
		}
		break;
	case NM_CLICK: 
		{
			ObjMan->ClearSelection();
			NMITEMACTIVATE* idat = (NMITEMACTIVATE*)hdr;
			UpdateDataSel();
			Refresher::Instance->OverviewRefresh();
			
		}
		break;
		
	case NM_DBLCLK: 
		{
			
			NMITEMACTIVATE* idat = (NMITEMACTIVATE*)hdr;
			if(idat->iItem!=-1)
			{
				EdGUIObject *gobj=(EdGUIObject *)m_List.GetItemData(idat->iItem);
				
				if(!MyTree->DrillDownTo(gobj))
				{
					ObjMan->SetProperties(gobj,this);
					m_List.SetItemText(idat->iItem,idat->iSubItem,gobj->GetName());
					Refresher::Instance->WorldRefresh();
				}
			}
		}
		break;


	case LVN_BEGINDRAG:
		{
			NMLISTVIEW *draginf =(NMLISTVIEW *)hdr;
			if(draginf->iItem!=-1)
			{
			COleDataSource pDataSource;
			pDataSource.DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE,NULL, &DropSource);
			}
		}
		break;

	}
	
	return res;
}

void CObjListView::UpdateDataSel()
{
	int i;
	
	for(i=0;i<m_List.GetItemCount();i++)
	{
		EdGUIObject *gobj=(EdGUIObject *)m_List.GetItemData(i);
		if(m_List.GetItemState(i,LVIS_SELECTED )) gobj->Select();
		else
			gobj->DeSelect();
	}	
	
	
}

void CObjListView::UpdateSelState()
{
	int i;
	
	for(i=0;i<m_List.GetItemCount();i++)
	{
		EdGUIObject *gobj=(EdGUIObject *)m_List.GetItemData(i);
		m_List.SetItemState(i,gobj->IsSelected()?LVIS_SELECTED:0,LVIS_SELECTED);
	}	
	
	
}

void CObjListView::DeleteSelected()
{
	bool asl=AllSelected();
	ObjMan->DeleteSelection();

	if(asl)
	{
	Refresher::Instance->WorldRefresh();
	}
	else
	{
	Refresh(MyList);
	}
}

bool CObjListView::AllSelected()
{
	int i;
	
	for(i=0;i<m_List.GetItemCount();i++)
	{
		EdGUIObject *gobj=(EdGUIObject *)m_List.GetItemData(i);
		if(m_List.GetItemState(i,LVIS_SELECTED )==0) return false;
	}	

	return true;
}

void CObjListView::AddSelectedToGroup(GUIObjectList *group)
{
if(group==MyList) return;
int i;
UndoCommand *chain=NULL;
	for(i=0;i<m_List.GetItemCount();i++)
	{
		EdGUIObject *gobj=(EdGUIObject *)m_List.GetItemData(i);
		if(gobj!=group && m_List.GetItemState(i,LVIS_SELECTED )) 
		{
			UndoCommand *cmd=new GroupCommand(gobj);
			if(chain) chain->Attach(cmd); else chain=cmd;
			
			group->MoveToGroup(gobj);
		}
	}	

if(chain)
	ObjMan->SaveUndoCommand(chain);

Refresh(MyList);
Refresher::Instance->OverviewRefresh();

}

void CObjListView::ListDropAt(CPoint &pnt)
{
if(CanListDropAt(pnt))
{
AddSelectedToGroup((GUIObjectList *)ObjectAtPoint(pnt));
}


}

EdGUIObject *CObjListView::ObjectAtPoint(CPoint &pnt)
{
UINT flags;
int idx;
idx=m_List.HitTest(pnt,&flags);

if(idx==-1) return NULL;
return (EdGUIObject *)m_List.GetItemData(idx);	
}


bool CObjListView::CanListDropAt(CPoint &pnt)
{
EdGUIObject *gobj=ObjectAtPoint(pnt);
if(gobj!=NULL && MyTree->InTree(gobj))
{
GUIObjectList *olist=(GUIObjectList *)gobj;
if(olist->CanTakeChildren()) return true;
}

return false;
}

void CObjListView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	
	CView::OnChar(nChar, nRepCnt, nFlags);
}

void CObjListView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
			switch(nChar)
			{
			case VK_DELETE:
				{
					DeleteSelected();
				}
				
			case VK_RETURN:
				{
					ObjMan->SetPropertiesOfSelected(this);
					Refresher::Instance->WorldRefresh();
				}
				break;
			}
	
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CObjListView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	
	CView::OnKeyUp(nChar, nRepCnt, nFlags);
}

