/***************************************************************************

  M.A.M.E.32  -  Multiple Arcade Machine Emulator for Win32
  Win32 Portions Copyright (C) 1997-2001 Michael Soderstrom and Chris Kirmse

  This file is part of MAME32, and may only be used, modified and
  distributed under the terms of the MAME license, in "readme.txt".
  By continuing to use, modify or distribute this file you indicate
  that you have read the license and understand and accept it fully.

***************************************************************************/
 
/***************************************************************************

  ColumnEdit.c

  Column Edit dialog

***************************************************************************/

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#include <commctrl.h>
#include <commdlg.h>

#include "resource.h"
#include "win32ui.h"

#ifdef JMAME
#include "MAME32.h"
#endif

// Returns TRUE if successful
int DoExchangeItem(HWND hFrom, HWND hTo, int nMinItem)
{
	LV_ITEM lvi;
	char	buf[80];
	int 	nFrom, nTo;

	nFrom = ListView_GetItemCount(hFrom);
	nTo   = ListView_GetItemCount(hTo);

	lvi.iItem = ListView_GetNextItem(hFrom, -1, LVIS_SELECTED | LVIS_FOCUSED);
	if (lvi.iItem < nMinItem)
	{
		if (lvi.iItem != -1) // Can't remove the first column
#ifdef JAPANESE
			MessageBox(0, "この項目は移動できません", MAME32NAME " - 項目の移動", IDOK);
#else
			MessageBox(0, "Cannot Move Selected Item", MAME32NAME " - Move Item", IDOK);
#endif
		SetFocus(hFrom);
		return FALSE;
	}
	lvi.iSubItem   = 0;
	lvi.mask	   = LVIF_PARAM | LVIF_TEXT;
	lvi.pszText    = buf;
	lvi.cchTextMax = sizeof(buf);
	if (ListView_GetItem(hFrom, &lvi))
	{
		// Add this item to the Show and delete it from Available
		ListView_DeleteItem(hFrom, lvi.iItem);
		lvi.iItem = ListView_GetItemCount(hTo);
		ListView_InsertItem(hTo, &lvi);
		ListView_SetItemState(hTo, lvi.iItem,
							  LVIS_FOCUSED | LVIS_SELECTED,
							  LVIS_FOCUSED | LVIS_SELECTED);
		SetFocus(hTo);
		return lvi.iItem;
	}
	return FALSE;
}

void DoMoveItem( HWND hWnd, BOOL bDown)
{
	LV_ITEM lvi;
	char	buf[80];
	int 	nMaxpos;
	
	lvi.iItem = ListView_GetNextItem(hWnd, -1, LVIS_SELECTED | LVIS_FOCUSED);
	nMaxpos = ListView_GetItemCount(hWnd);
	if (lvi.iItem == -1 || 
		(lvi.iItem <  2 && bDown == FALSE) || // Disallow moving First column
		(lvi.iItem == 0 && bDown == TRUE)  || // ""
		(lvi.iItem == nMaxpos - 1 && bDown == TRUE))
	{
		SetFocus(hWnd);
		return;
	}
	lvi.iSubItem   = 0;
	lvi.mask	   = LVIF_PARAM | LVIF_TEXT;
	lvi.pszText    = buf;
	lvi.cchTextMax = sizeof(buf);
	if (ListView_GetItem(hWnd, &lvi))
	{
		// Add this item to the Show and delete it from Available
		ListView_DeleteItem(hWnd, lvi.iItem);
		lvi.iItem += (bDown) ? 1 : -1;
		ListView_InsertItem(hWnd,&lvi);
		ListView_SetItemState(hWnd, lvi.iItem,
							  LVIS_FOCUSED | LVIS_SELECTED,
							  LVIS_FOCUSED | LVIS_SELECTED);
		if (lvi.iItem == nMaxpos - 1)
			EnableWindow(GetDlgItem(GetParent(hWnd), IDC_BUTTONMOVEDOWN), FALSE);
		else
			EnableWindow(GetDlgItem(GetParent(hWnd), IDC_BUTTONMOVEDOWN), TRUE);

		if (lvi.iItem < 2)
			EnableWindow(GetDlgItem(GetParent(hWnd), IDC_BUTTONMOVEUP),   FALSE);
		else
			EnableWindow(GetDlgItem(GetParent(hWnd), IDC_BUTTONMOVEUP),   TRUE);

		SetFocus(hWnd);
	}
}

INT_PTR CALLBACK ColumnDialogProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	static HWND hShown;
	static HWND hAvailable;
	static int  shown[COLUMN_MAX];
	static int  order[COLUMN_MAX];
	static BOOL showMsg = FALSE;
	int         nShown;
	int         nAvail;
	int         i, nCount = 0;
	LV_ITEM     lvi;

	switch (Msg)
	{
	case WM_INITDIALOG:
		hShown	   = GetDlgItem(hDlg, IDC_LISTSHOWCOLUMNS);
		hAvailable = GetDlgItem(hDlg, IDC_LISTAVAILABLECOLUMNS);
		GetColumnOrder(order);
		GetColumnShown(shown);

		showMsg = TRUE;
		nShown	= 0;
		nAvail	= 0;
						
		lvi.mask	  = LVIF_TEXT | LVIF_PARAM; 
		lvi.stateMask = 0;				   
		lvi.iSubItem  = 0; 
		lvi.iImage	  = -1;

		/* Get the Column Order and save it */
		GetRealColumnOrder(order);

#if 0
        {
            char tmp[80];
            
            sprintf(tmp,"ColumnOrder: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d, %d",
                order[0], order[1], order[2], order[3], order[4],
                order[5], order[6], order[7], order[8], order[9], order[10]);
            MessageBox(0, tmp, "Column Order", IDOK);
        }
#endif
		for (i = 0 ; i < COLUMN_MAX; i++)
		{		 
			lvi.pszText = column_names[order[i]];
			lvi.lParam	= order[i];

			if (shown[order[i]])
			{
				lvi.iItem = nShown;
				ListView_InsertItem(hShown, &lvi);
				nShown++;
			}
			else
			{
				lvi.iItem = nAvail;
				ListView_InsertItem(hAvailable, &lvi);
				nAvail++;
			}
		}
		return TRUE;

	case WM_NOTIFY:
		{
			NMHDR *nm = (NMHDR *)lParam;
			NM_LISTVIEW *pnmv;
			int 		nPos;
			
			switch (nm->code)
			{
			case LVN_KEYDOWN:
				{
				}
				break;
				
			case NM_DBLCLK:
				// Do Data Exchange here, which ListView was double clicked?
				switch (nm->idFrom)
				{
				case IDC_LISTAVAILABLECOLUMNS:
					// Move selected Item from Available to Shown column
					nPos = DoExchangeItem(hAvailable, hShown, 0);
					if (nPos)
					{
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONADD),	   FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONREMOVE),   TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEUP),   TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEDOWN), FALSE);
					}
					break;

				case IDC_LISTSHOWCOLUMNS:
					// Move selected Item from Show to Available column
					if (DoExchangeItem(hShown, hAvailable, 1))
					{
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONADD)  ,    TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONREMOVE),   FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEUP),   FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEDOWN), FALSE);
					}
					break;
				}
				return TRUE;
				
			case LVN_ITEMCHANGED:
				// Don't handle this message for now
				pnmv = (NM_LISTVIEW *)nm;
				if (//!(pnmv->uOldState & LVIS_SELECTED) &&
					(pnmv->uNewState  & LVIS_SELECTED))
				{
					if (pnmv->iItem == 0 && pnmv->hdr.idFrom == IDC_LISTSHOWCOLUMNS)
					{
						// Don't allow selecting the first item
						ListView_SetItemState(hShown, pnmv->iItem,
							0, LVIS_FOCUSED | LVIS_SELECTED);
						if (showMsg)
						{
#ifdef JAPANESE
							MessageBox(0,"この項目の選択は許可されていません", MAME32NAME " - 項目の選択", IDOK);
#else
							MessageBox(0, "Selecting this Item is not permitted", MAME32NAME " - Select Item", IDOK);
#endif
							showMsg = FALSE;
						}
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONREMOVE),   FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEUP),   FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEDOWN), FALSE);
						SetFocus(GetDlgItem(hDlg,IDOK));
						return TRUE;
					}
					else
						showMsg = TRUE;
				}
				break;

			case NM_CLICK:
				switch (nm->idFrom)
				{
				case IDC_LISTAVAILABLECOLUMNS:
					if (ListView_GetItemCount(nm->hwndFrom) != 0)
					{
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONADD),	   TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONREMOVE),   FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEDOWN), FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEUP),   FALSE);
					}
					break;

				case IDC_LISTSHOWCOLUMNS:
					if (ListView_GetItemCount(nm->hwndFrom) != 0)
					{
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONADD),	   FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONREMOVE),   TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEDOWN), TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEUP),   TRUE);
					}
					break;
				}
				return TRUE;
			}
		}
		return FALSE;

	case WM_COMMAND:
	   {
			WORD wID	  = GET_WM_COMMAND_ID(wParam, lParam);
			HWND hWndCtrl = GET_WM_COMMAND_HWND(wParam, lParam);
			int  nPos = 0;

			switch (wID)
			{
				case IDC_BUTTONADD:
					// Move selected Item in Available to Shown
					nPos = DoExchangeItem(hAvailable, hShown, 0);
					if (nPos)
					{
						EnableWindow(hWndCtrl,FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONREMOVE),   TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEUP),   TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEDOWN), FALSE);
					}
					break;

				case IDC_BUTTONREMOVE:
					// Move selected Item in Show to Available
					if (DoExchangeItem( hShown, hAvailable, 1))
					{
						EnableWindow(hWndCtrl,FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONADD),	   TRUE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEUP),   FALSE);
						EnableWindow(GetDlgItem(hDlg, IDC_BUTTONMOVEDOWN), FALSE);
					}
					break;

				case IDC_BUTTONMOVEDOWN:
					// Move selected item in the Show window up 1 item
					DoMoveItem(hShown, TRUE);
					break;

				case IDC_BUTTONMOVEUP:
					// Move selected item in the Show window down 1 item
					DoMoveItem(hShown, FALSE);
					break;

				case IDOK:
					// Save users choices
					nShown = ListView_GetItemCount(hShown);
					nAvail = ListView_GetItemCount(hAvailable);
					nCount = 0;
					for (i = 0; i < nShown; i++)
					{
						lvi.iSubItem = 0;
						lvi.mask     = LVIF_PARAM;
						lvi.pszText  = 0;
						lvi.iItem    = i;
						ListView_GetItem(hShown, &lvi);
						order[nCount++]   = lvi.lParam;
						shown[lvi.lParam] = TRUE;
					}
					for (i = 0; i < nAvail; i++)
					{
						lvi.iSubItem = 0;
						lvi.mask     = LVIF_PARAM;
						lvi.pszText  = 0;
						lvi.iItem    = i;
						ListView_GetItem(hAvailable, &lvi);
						order[nCount++]   = lvi.lParam;
						shown[lvi.lParam] = FALSE;
					}
#if 0
					{
						char tmp[80];
						sprintf(tmp,"Shown (%d) - Hidden (%d)",nShown,nAvail);
						MessageBox(0,tmp,"List Counts",IDOK);
						sprintf(tmp,"ColumnOrder: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d, %d",
							order[0], order[1], order[2], order[3], order[4],
							order[5], order[6], order[7], order[8], order[9], shown[10]);
						MessageBox(0,tmp,"Column Order", IDOK);
						sprintf(tmp,"ColumnShown: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d, %d",
							shown[0], shown[1], shown[2], shown[3], shown[4],
							shown[5], shown[6], shown[7], shown[8], shown[9], shown[10]);
						MessageBox(0,tmp,"Column Shown", IDOK);
					}
#endif
					SetColumnOrder(order);
					SetColumnShown(shown);
					EndDialog(hDlg, 1);
					return TRUE;

				case IDCANCEL:
					EndDialog(hDlg, 0);
					return TRUE;
			}
		}
		break;
	}
	return 0;
}



