/*-----------------------------------------------------------------------------
[名称]	AAListView.cpp
[概要]	AAリスト表示クラスの実装
[備考]	なし
[履歴]	2003-03-17	NC		新規作成(moralog)
-----------------------------------------------------------------------------*/


//-----------------------------------------------------------------------------
// インクルード
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "hebope.h"
#include "AAHanger.h"
#include "AAListView.h"
#include "MainFrm.h"
#include "HebopeDoc.h"
#include "ExeCommon.h"
#include <afxole.h>
#include "../common/Common.h"
#include <afxadv.h>
#include "EditAADlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAAListView

IMPLEMENT_DYNCREATE(CAAListView, CListViewEx)

CAAListView::CAAListView()
:	m_pNode( NULL )
,	m_iSortedBy( 1 )
{
}

CAAListView::~CAAListView()
{
}


BEGIN_MESSAGE_MAP(CAAListView, CListViewEx)
	//{{AFX_MSG_MAP(CAAListView)
	ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemchanged)
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_COMMAND(IDM_LIST_DELETEINDEX, OnListDeleteindex)
	ON_COMMAND(IDM_LIST_EDITAA, OnListEditaa)
	ON_COMMAND(IDM_LIST_ADDAA, OnListAddaa)
	ON_COMMAND(IDM_EDIT_APPEND, OnEditAppend)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAAListView 描画

void CAAListView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: この位置に描画用のコードを追加してください
}

/////////////////////////////////////////////////////////////////////////////
// CAAListView 診断

#ifdef _DEBUG
void CAAListView::AssertValid() const
{
	CListViewEx::AssertValid();
}

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

/////////////////////////////////////////////////////////////////////////////
// CAAListView メッセージ ハンドラ

void CAAListView::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

	// AAが選択されたのでEditViewに表示する
	((CMainFrame*)::AfxGetMainWnd())->ReflectEditView();
	
	*pResult = 0;
}


/*-----------------------------------------------------------------------------
[名称]	表示更新
[機能]	ドキュメント内容をビューに反映する
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CAAListView::ReflectView(
	CCategoryNode*	pNode
)
{
	if ( pNode != NULL )
	{
		// 扱っているノード情報変更をメモ
		m_pNode = pNode;

		GetListCtrl().DeleteAllItems();
		GetListCtrl().SetItemCount( pNode->GetIndexCount() );

		// リストビューに追加してみるテスト
		long idxLine;
		CAAHanger*	pAAHanger = ((CHebopeDoc*)::GetMainFrame()->GetActiveDocument())->GetAAHanger();

		CListCtrl*	pListCtrl = &GetListCtrl();
		pListCtrl->SetItemCount( pNode->GetIndexCount() );//, LVSICF_NOSCROLL );
		for( idxLine=0 ; idxLine<pNode->GetIndexCount() ; idxLine++ )
		{
			int	idxListItem = pListCtrl->InsertItem(
				idxLine,
				pAAHanger->GetName( pNode->GetIndex( idxLine ) )
			);
			pListCtrl->SetItemData( idxListItem, idxLine );
		}

		// ソート設定を反映
		GetListCtrl().SortItems( CompareAA, m_iSortedBy );
	}
}


/*-----------------------------------------------------------------------------
[名称]	要素比較
[機能]	
[戻値]	なし
[備考]	CListCtrl::SortItems() のヘルプ参照。
-----------------------------------------------------------------------------*/
int CALLBACK CAAListView::CompareAA(
	LPARAM lParam1,
	LPARAM lParam2,
	LPARAM lParamSort
)
{
	CAAListView*	pListView = ::GetMainFrame()->GetListView();

	long		idxAA1 = pListView->m_pNode->GetIndex( (long)(lParam1) );
	long		idxAA2 = pListView->m_pNode->GetIndex( (long)(lParam2) );
	bool		bComplementResult;
	int			result = 0;

	if (lParamSort < 0)
	{
		lParamSort = -lParamSort;
		bComplementResult = true;
	}
	else
	{
		bComplementResult = false;
	}
	lParamSort--;

	// Sort window data by predefined sort criterion
	// (secondary sort criterion is always the window handle)
	// 評価が同じときはcontinueさせる
	for ( ; TRUE ; lParamSort++ )
	{
		switch (lParamSort)
		{
		case 0:
			{
				CAAHanger*	pAAHanger = ((CHebopeDoc*)::GetMainFrame()->GetActiveDocument())->GetAAHanger();
				CString&	strName1 = pAAHanger->GetName( idxAA1 );
				CString&	strName2 = pAAHanger->GetName( idxAA2 );

				if ( strName1 < strName2 )
				{
					result = -1;
				}
				else
				if ( strName1 > strName2 )
				{
					result = 1;
				}
				else
				{
					continue;
				}
			}
			break;

		case 1:

		default:
//			ASSERT( false );
			break;
		}
		break;
	}

  if (bComplementResult) result = -result;
  return result;
}


/*-----------------------------------------------------------------------------
[名称]	ヘッダカラムクリックハンドラ
[機能]	要素のソート処理。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CAAListView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

	int iSortedBy = pNMListView->iSubItem;
	iSortedBy = iSortedBy+1;
	if( iSortedBy != m_iSortedBy )
	{
		m_iSortedBy = iSortedBy;
	}
	else
	{
		m_iSortedBy = -iSortedBy;
	}

	SetSortColumn( m_iSortedBy );
	GetListCtrl().SortItems( CompareAA, m_iSortedBy );

	*pResult = 0;
}


/*-----------------------------------------------------------------------------
[名称]	左クリックハンドラ
[機能]	ドラッグの開始。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CAAListView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CListViewEx::OnLButtonDown(nFlags, point);

	POSITION pos = GetListCtrl().GetFirstSelectedItemPosition();
	if (pos != NULL)
	{
		// 有効なAAデータを掴んだ場合
		long	idxLine = GetListCtrl().GetNextSelectedItem( pos );

		// AAデータを取得
		CAAListView*	pListView = ::GetMainFrame()->GetListView();
		long idxItem = (long)(GetListCtrl().GetItemData( idxLine ));
		long idxAA = pListView->m_pNode->GetIndex( idxItem );


		// ドラッグに関するデータを用意する
		// ツリーへのドラッグ時にツリーはリスト内で選択された要素を直接見にくるので
		// ここで用意するデータはダミー。（はっきりいって何も渡さなくてよい）
		CString str; 
		str.Format( "%d", idxAA );
		COleDataSource		Source;
		CSharedFile sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT); 
		sf.Write(str,str.GetLength()); 

		HGLOBAL hMem = sf.Detach(); 
		if (!hMem) return;

		UINT	uiFormat = ::RegisterClipboardFormat( g_strAADataFormat );
		Source.CacheGlobalData( uiFormat, hMem );
        DROPEFFECT result = Source.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE);
        if( result == DROPEFFECT_MOVE )
		{
			DeleteSelectedItemz();
        }
        return;
    }

}


/*-----------------------------------------------------------------------------
[名称]	選択要素削除
[機能]	選択された要素の削除。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CAAListView::DeleteSelectedItemz() 
{
	// 選択されていた領域を削除する
	POSITION pos = GetListCtrl().GetFirstSelectedItemPosition();
	CDWordArray		adwLinez;
	while( pos != NULL )
	{
		long idxLine = GetListCtrl().GetNextSelectedItem( pos );
		adwLinez.Add( idxLine );
	}
	long	idxDeleteItem;
	for( idxDeleteItem=adwLinez.GetSize()-1 ; idxDeleteItem>=0 ; idxDeleteItem-- )
	{
		CAAListView*	pListView = ::GetMainFrame()->GetListView();
		long idxLine = adwLinez[ idxDeleteItem ];
		long idxItem = (long)(GetListCtrl().GetItemData( idxLine ));
		long idxAA = pListView->m_pNode->GetIndex( idxItem );

		// カテゴリツリーのノードから削除
		Node()->DeleteIndex( idxItem );

		// 再描画
		ReflectView( Node() );
	}

	// ドキュメントに変更あり！
	::NotifyModified();
}


/*-----------------------------------------------------------------------------
[名称]	右クリックハンドラ
[機能]	ポップアップ表示。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CAAListView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	CListViewEx::OnRButtonDown(nFlags, point);

	// メニューのロード
	CMenu menu;
	VERIFY(menu.LoadMenu(IDR_LISTPOPUP));
	CMenu* pPopup = menu.GetSubMenu(0);

	// Enable制御
	POSITION pos = GetListCtrl().GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		pPopup->EnableMenuItem( IDM_LIST_EDITAA, FALSE );
		pPopup->EnableMenuItem( IDM_LIST_DELETEINDEX, FALSE );
	}

	// ポップアップメニューの表示
	CPoint posCursor( point );
	ClientToScreen( &posCursor );
	pPopup->TrackPopupMenu(
		TPM_LEFTALIGN | TPM_RIGHTBUTTON,
		posCursor.x, posCursor.y,
		::AfxGetMainWnd()
	);
}


/*-----------------------------------------------------------------------------
[名称]	削除ハンドラ
[機能]	選択された要素の削除。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CAAListView::OnListDeleteindex() 
{
	DeleteSelectedItemz();	
}


/*-----------------------------------------------------------------------------
[名称]	編集ハンドラ
[機能]	選択されたＡＡの編集。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CAAListView::OnListEditaa() 
{
	// 選択されている要素を得る
	POSITION pos = GetListCtrl().GetFirstSelectedItemPosition();
	CDWordArray		adwLinez;
	if( pos != NULL )
	{
		CAAListView*	pListView = ::GetMainFrame()->GetListView();
		long idxLine = GetListCtrl().GetNextSelectedItem( pos );
		long idxItem = (long)(GetListCtrl().GetItemData( idxLine ));
		long idxAA = pListView->m_pNode->GetIndex( idxItem );

		CEditAADlg	dlg;
		CAAHanger*	pAAHanger = ((CHebopeDoc*)::GetMainFrame()->GetActiveDocument())->GetAAHanger();
		dlg.m_strName = pAAHanger->GetName( idxAA );
		dlg.m_strAA = pAAHanger->GetAA( idxAA );
		if ( dlg.DoModal() == IDOK )
		{
			// 新規要素を追加する
			long	idxAANew = ::GetMainFrame()->AAAppend(
				dlg.m_strName,
				dlg.m_strAA
			);

			// m_pNode の情報を書き換える
			// インデクス
			m_pNode->SetIndex(
				idxItem,
				idxAANew
			);

			// リスト更新
			ReflectView( m_pNode );
			GetListCtrl().SetItemState(
				idxLine,
				LVIS_SELECTED, LVIS_SELECTED
			);
		}
	}
}


/*-----------------------------------------------------------------------------
[名称]	AAの新規追加ハンドラ
[機能]	メニューハンドラ。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CAAListView::OnListAddaa()
{
	CEditAADlg	dlg;
	dlg.m_strName = _T("（新規ＡＡ）");
	if ( dlg.DoModal() == IDOK )
	{
		// 新規要素を追加する
		long	idxAANew = ::GetMainFrame()->AAAppend(
			dlg.m_strName,
			dlg.m_strAA
		);

		// ノードへ追加
		m_pNode->AddIndex(
			idxAANew
		);

		// ビューの内容更新
		ReflectView( m_pNode );

		for( long idxLine=0 ; idxLine<GetListCtrl().GetItemCount() ; idxLine++ )
		{
			long idxItem = (long)(GetListCtrl().GetItemData( idxLine ));
			long idxAA = m_pNode->GetIndex( idxItem );
			if ( idxAA == idxAANew )
			{
				GetListCtrl().SetItemState(
					idxLine,
					LVIS_SELECTED, LVIS_SELECTED
				);
				break;
			}
		}
	}
}

void CAAListView::OnEditAppend() 
{
	// TODO: この位置にコマンド ハンドラ用のコードを追加してください
	
}
