
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
//	FILE	: List.cpp
//	AUTHOR	: Catalin Cocos
//__________________________________________________________________________________________________

#include "stdinc.h"
#include "app.h"
#include "list.h"
#include "resource.h"


WNDPROC ListIWP;
WNDPROC OutIWP;
WNDPROC FilterIWP;

CTip* pListTip;

void SetFilterItemState( int idx )
{
	if( idx<0) return;
	char Ext[_MAX_EXT];
	LV_ITEM GotItem = { LVIF_TEXT, idx, 0, 0, 0, Ext, _MAX_EXT };
	LV_ITEM testItem = { LVIF_STATE, idx, 0, 0, ~LVIS_FOCUSED };
	ListView_GetItem( hWFilter, &testItem);
	if(testItem.state & LSTATE_LOCKED)
		return;
	testItem.state ^= (LSTATE_UNCHECKED|LSTATE_CHECKED);
	BOOL Enabled = testItem.state & LSTATE_CHECKED;
	if(testItem.state & LVIS_SELECTED)
	{
		int maxCnt = ListView_GetSelectedCount( hWFilter );
		int i = 0;
		for( testItem.iItem = -1; i<maxCnt; i++ )
		{
			GotItem.iItem = testItem.iItem = ListView_GetNextItem( hWFilter, testItem.iItem, LVNI_SELECTED );
			ListView_SetItem( hWFilter, &testItem);
			ListView_GetItem( hWFilter, &GotItem);
			CnvEng.EnableExtension( Ext, Enabled );
		}
	}
	else
	{
		ListView_SetItem( hWFilter, &testItem); 
		ListView_GetItem( hWFilter, &GotItem);
		CnvEng.EnableExtension( Ext, Enabled );
	}
}


LRESULT CALLBACK FilterWndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
	switch(msg)
	{
	case WM_SETFOCUS: nFocusWnd = FOCUS_FILTER; break;
	case WM_COMMAND:
		switch(LOWORD(wp))
		{
		case ID_SELECT_TOGGLE:
			SetFilterItemState( ListView_GetNextItem( hwnd, -1, LVNI_FOCUSED ) );
			return 0;
		case ID_SELECT_ALL:
			{
				LV_ITEM testItem = { LVIF_STATE, 0, 0, LVIS_SELECTED, LVIS_SELECTED };
				for(testItem.iItem = ListView_GetItemCount( hwnd )-1; testItem.iItem>=0; testItem.iItem--)
					ListView_SetItem( hwnd, &testItem);
				return 0;
			}
		}
		break;
	case WM_LBUTTONDOWN:
		{
			LV_HITTESTINFO ht = {{ LOWORD(lp), HIWORD(lp)}};
			ListView_HitTest( hwnd, &ht);
			if(ht.iItem >=0 && ht.flags == LVHT_ONITEMSTATEICON)
			{
				SetFocus( hwnd );
				SetFilterItemState( ht.iItem );
				return 0;
			}
		}
		break;
	}
	return CallWindowProc( (int(CALLBACK*)())FilterIWP, hwnd, msg, wp, lp);
}


LRESULT CALLBACK OutWndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
	switch(msg)
	{
	case WM_SETFOCUS:
		nFocusWnd = FOCUS_OUT; break;
	}
	return CallWindowProc( (int(CALLBACK*)())OutIWP, hwnd, msg, wp, lp);
}


void SetListItemState( int idx );

LRESULT CALLBACK ListWndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
	static int CrtItem = -1;
	static BOOL bHelp = FALSE;
	static BOOL bReady = TRUE;
	switch(msg)
	{
	case WM_USER+10:
		ShowItemPath( hwnd, wp);
		bReady = FALSE;
		break;
	case WM_SETFOCUS: nFocusWnd = FOCUS_LIST; break;
	case WM_COMMAND:
		switch(LOWORD(wp))
		{
		case ID_DELETE:
			{
				int maxCnt = ListView_GetSelectedCount( hwnd );
				for( int i = 0, j = -1; i<maxCnt; i++, j-- )
					DeleteListItem(j = ListView_GetNextItem( hwnd, j, LVNI_SELECTED ));
				if(maxCnt)
				{
					i = (j==ListView_GetItemCount( hwnd )-1?j:j+1);
					if(i>=0)
					{
						ListView_SetItemState(hwnd, i, LVIS_SELECTED, LVIS_SELECTED );
					}
					else CrtItem = -1;
					PostMessage( hwnd, WM_USER+10, i, 0);
				}
			}
			return 0;
		case ID_SELECT_TOGGLE:
			SetListItemState( ListView_GetNextItem( hwnd, -1, LVNI_FOCUSED ));
			return 0;
		case ID_SELECT_ALL:
			{
				LV_ITEM testItem = { LVIF_STATE, 0, 0, LVIS_SELECTED, LVIS_SELECTED };
				for(testItem.iItem = ListView_GetItemCount( hwnd )-1; testItem.iItem>=0; testItem.iItem--)
					ListView_SetItem( hwnd, &testItem);
				return 0;
			}
		}
		break;
	case WM_MOUSEMOVE:
		{
			LV_HITTESTINFO ht = {{ LOWORD(lp), HIWORD(lp)}};
			ListView_HitTest( hwnd, &ht);
			if(ht.iItem >=0 )
			{
				if(ht.iItem != CrtItem && ht.flags == LVHT_ONITEMLABEL)
				{
					ShowItemPath( hwnd, ht.iItem);
					CrtItem = ht.iItem;
				}
			}
			else if(bReady && ht.flags &(LVHT_ABOVE|LVHT_BELOW|LVHT_TORIGHT|LVHT_TOLEFT))
			{
				CrtItem = -1;
				pListTip->Show( NULL, hwnd );
			} 
			bReady = TRUE;
		}
		break;
	case WM_KILLFOCUS:
	case WM_RBUTTONUP:
		pListTip->Show( NULL, hwnd );
		CrtItem = -1;
		bHelp = FALSE;
		break;
	case WM_RBUTTONDOWN:
		{
			LV_HITTESTINFO ht = {{ LOWORD(lp), HIWORD(lp)}};
			ListView_HitTest( hwnd, &ht);
			if(ht.iItem >=0 && ht.flags == LVHT_ONITEMSTATEICON)
				{
					POINT p = { LOWORD(lp)-1, HIWORD(lp)-1};
					ClientToScreen( hwnd, &p);
					pListTip->Show( "Press this button to toggle the file activation", hwnd);//, &p );
					bHelp = TRUE;
				}
		}
		break;
	case WM_LBUTTONDOWN:
		{
			LV_HITTESTINFO ht = {{ LOWORD(lp), HIWORD(lp)}};
			ListView_HitTest( hwnd, &ht);
			if(ht.iItem >=0 && ht.flags == LVHT_ONITEMSTATEICON)
			{
				SetFocus( hwnd );
				SetListItemState( ht.iItem );
				return 0;
			}
		}
		break;
	case WM_DROPFILES:
		{
			char buffer[_MAX_PATH +1] = "";
			int files = DragQueryFile((HDROP)wp,0xffffffff,buffer,_MAX_PATH);
			for(int i = 0; i<files; i++)
			{
				DragQueryFile((HDROP)wp,i,buffer,_MAX_PATH);
				InsertCollectionFile(hwnd, buffer);
			}
			SetFocus(hwnd);
		}
		DragFinish((HDROP)wp);
		break;
	case WM_DESTROY: DeleteCollectionList(); break;
	}
	return CallWindowProc( (int(CALLBACK*)())ListIWP, hwnd, msg, wp, lp);
}

void SetListItemState( int idx )
{
	if( idx<0) return;
	LV_ITEM testItem = { LVIF_STATE, idx, 0, 0, ~LVIS_FOCUSED };
	ListView_GetItem( hWList, &testItem);
	testItem.state ^= (LSTATE_UNCHECKED|LSTATE_CHECKED);
	if(testItem.state & LVIS_SELECTED)
	{
		int maxCnt = ListView_GetSelectedCount( hWList );
		int i = 0;
		for( testItem.iItem = -1; i<maxCnt; i++ )
		{
			testItem.iItem = ListView_GetNextItem( hWList, testItem.iItem, LVNI_SELECTED );
			ListView_SetItem( hWList, &testItem);
		}
	}
	else ListView_SetItem( hWList, &testItem); 
}

void DeleteCollectionList()
{
	int maxCnt = ListView_GetItemCount( hWList );
	for( int i = maxCnt-1 ; i>=0; i-- )
		DeleteListItem( i );
}

void DeleteListItem(int idx)
{
	LV_ITEM it = {LVIF_PARAM, idx, 0};
	ListView_GetItem( hWList, &it);
	delete[] (char*)it.lParam;
	ListView_DeleteItem( hWList, idx);
}


void ShowItemPath( HWND hwnd, int iItem)
{
	if(iItem>=0)
	{
		LV_ITEM testItem = { LVIF_PARAM, iItem, 0 };
		ListView_GetItem( hwnd, &testItem);
		char buffer[_MAX_FNAME+1];
		ListView_GetItemText( hwnd, iItem, 0, buffer, _MAX_FNAME+1)
		RECT r;
		ListView_GetItemRect( hwnd, iItem, &r, LVIR_LABEL );
		int right = r.left + 5 + ListView_GetStringWidth( hwnd, buffer);
		int top = r. top;
		GetClientRect( hwnd, &r);
		POINT p = { min(right, r.right), top};
		ClientToScreen( hwnd, &p);
		pListTip->Show( (char*)testItem.lParam, hwnd, &p );
	}
	else
		pListTip->Show( NULL, NULL);
}

void InsertCollectionFile(HWND hwnd, char* buffer)
{
	char Fname[_MAX_FNAME+1];
	char Ext[_MAX_EXT+1] = {0, 0};
	_splitpath(buffer,NULL,NULL,Fname,Ext);
	if(!stricmp(Ext+1,"txt") || !stricmp(Ext+1,"log"))
	{
		LV_FINDINFO fi = { LVFI_STRING, Fname };
		int idx = ListView_FindItem( hwnd, -1, &fi);
		if(idx>=0)
		{
			LV_ITEM testItem = { LVIF_PARAM, idx, 0};
			ListView_GetItem( hwnd, &testItem);
			if(!stricmp(buffer, (char*)testItem.lParam))
				return;
		}
		LV_ITEM a = {LVIF_TEXT|LVIF_STATE|LVIF_PARAM,ListView_GetItemCount(hwnd),0,
					LVIS_SELECTED|LVIS_FOCUSED|LSTATE_CHECKED,0,
					Fname, 0,0,(LPARAM)lstrcpy( new char[strlen(buffer)+1],buffer )};
		ListView_InsertItem( hwnd , &a);
	}
}