/*******************************************************************************
  TPI - flexible but useless plug-in framework.
  Copyright (C) 2002-2009 Silky

  This library is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free
  Software Foundation; either version 2.1 of the License, or (at your option)
  any later version.

  This library is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  for more details.

  You should have received a copy of the GNU Lesser General Public License along
  with this library; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

  $Id: cls_listctrl.cpp 359 2010-09-25 07:43:45Z sirakaba $
*******************************************************************************/

#include "lychee.h"

#include "cls_listctrl.h"
#include "dlg_make.h"
#include "frm_main.h"
#include "functions.h"

//******************************************************************************
// myListCtrl
//******************************************************************************

IMPLEMENT_DYNAMIC_CLASS(myListCtrl, wxListView)

//******************************************************************************
// Event Table.
//******************************************************************************

BEGIN_EVENT_TABLE(myListCtrl, wxListView)
	// ListView
	EVT_LIST_COL_CLICK(XRCID("ListView"), myListCtrl::OnColClick)
END_EVENT_TABLE()

//******************************************************************************
// Event handler.
//******************************************************************************

wxString myListCtrl::OnGetItemText(long i, long column) const
{
	// リストビューに項目を追加。
	switch (column)
	{
	case 0:
		return this->showFileInfo[i].fnFileName.GetFullName();
	case 1:
		return wxString::Format(wxString("%" wxLongLongFmtSpec "u"), this->showFileInfo[i].nUnpackedSize);
	case 2:
		return wxString::Format(wxString("%" wxLongLongFmtSpec "u"), this->showFileInfo[i].nPackedSize);
	case 3:
		return wxString::Format(wxT("%3.1f%%"), this->showFileInfo[i].wCompressRatio / 10.0);
	case 4:
		return this->showFileInfo[i].szMethod;
	case 5:
	{
		wxString szTemp = wxT("---w-");
		szTemp[0] = this->showFileInfo[i].dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? wxT('d') : 
		            this->showFileInfo[i].dwAttribute & TPI_ATTRIBUTE_ARCHIVE   ? wxT('a') : wxT('-');
		szTemp[1] = this->showFileInfo[i].dwAttribute & TPI_ATTRIBUTE_SYSTEM    ? wxT('s') : wxT('-');
		szTemp[2] = this->showFileInfo[i].dwAttribute & TPI_ATTRIBUTE_HIDDEN    ? wxT('h') : wxT('-');
		szTemp[3] = this->showFileInfo[i].dwAttribute & TPI_ATTRIBUTE_READONLY  ? wxT('r') : wxT('w');
		szTemp[4] = this->showFileInfo[i].dwAttribute & TPI_ATTRIBUTE_ENCRYPTED ? wxT('g') : wxT('-');
		return szTemp;
	}
	case 6:
		return this->showFileInfo[i].tmModified.Format(_("%Y/%m/%d %H:%M:%S"));
	case 7:
		return this->showFileInfo[i].fnFileName.GetPath();
	case 8:
		return GetFileTypeName(this->showFileInfo[i].fnFileName);
	case 9:
		return wxString::Format(wxString("%" wxLongLongFmtSpec "u"), this->showFileInfo[i].nFileId);
	case 10:
		return this->showFileInfo[i].szComment;
	default:
		return wxEmptyString;
	}
}

int myListCtrl::OnGetItemImage(long i) const
{
	wxIcon icon = GetFileTypeIcon(this->showFileInfo[i].fnFileName);
	g_hIconLL.Add(icon);
	// wxGTKで16x16のアイコンが表示できるようリサイズしておく。
#ifdef __WINDOWS__
	return g_hIconLS.Add(icon);
#else
	return g_hIconLS.Add(icon.ConvertToImage().Rescale(16, 16));
#endif
}

wxListItemAttr * myListCtrl::OnGetItemAttr(long i) const
{
	return
		this->showFileInfo[i].eDanger                               ? (wxListItemAttr *) & this->atDangerItem : 
		this->showFileInfo[i].dwAttribute & TPI_ATTRIBUTE_ENCRYPTED ? (wxListItemAttr *) & this->atEncryptedItem : NULL;
}

void myListCtrl::OnColClick(wxListEvent& e)
{
	g_nSortColumn = e.GetColumn();
	g_fSortAscend = ! (g_nSortColumn == e.GetColumn() && g_fSortAscend);

	// ソート。
	this->showFileInfo.Sort(& ListCtrlCompareProc);
	this->SetItemCount(this->showFileInfo.GetCount());
	this->RefreshItems(0, this->showFileInfo.GetCount() - 1);
}

//******************************************************************************
//    諸処理関数
//******************************************************************************

#define NumCmp(member) (item1->member < item2->member) ? -1 : ((item1->member > item2->member) ? 1 : 0)

int ListCtrlCompareProc(TPI_FILEINFO ** pItem1, TPI_FILEINFO ** pItem2)
{
	TPI_FILEINFO * item1 = * pItem1, * item2 = * pItem2;
	return (g_fSortAscend ? 1 : -1) * (
		g_nSortColumn == 0 ? ::wxStricmp(item1->fnFileName.GetFullName(), item2->fnFileName.GetFullName()) : // Filename
		g_nSortColumn == 1 ? NumCmp(nUnpackedSize) : // Unpacked
		g_nSortColumn == 2 ? NumCmp(nPackedSize) : // Packed
		g_nSortColumn == 3 ? NumCmp(wCompressRatio) : // Ratio
		g_nSortColumn == 6 ? NumCmp(tmModified) : // Last modified
		g_nSortColumn == 7 ? ::wxStricmp(item1->fnFileName.GetPath(), item2->fnFileName.GetPath()) : // Path
		g_nSortColumn == 8 ? ::wxStricmp(GetFileTypeName(item1->fnFileName), GetFileTypeName(item2->fnFileName)) : // Type
		g_nSortColumn == 9 ? NumCmp(nFileId) : // No
		g_nSortColumn == 10? ::wxStricmp(item1->szComment, item2->szComment) : // Comment
		0);
}
