//-----------------------------------------------------------------------------
#include "DeviceListCtrl.h"
#include "DeviceConfigureFrame.h"
#include "KernelDriverUpdate.h"
#include "LogOutputHandlerDlg.h"
#include <string>

BEGIN_EVENT_TABLE(DeviceListCtrl, wxListCtrl)
	EVT_LIST_COL_CLICK(LIST_CTRL, DeviceListCtrl::OnColClick)
	EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, DeviceListCtrl::OnActivated)
	EVT_LIST_ITEM_SELECTED(LIST_CTRL, DeviceListCtrl::OnSelected)
	EVT_LIST_ITEM_RIGHT_CLICK(LIST_CTRL, DeviceListCtrl::OnItemRightClick)
	EVT_LIST_ITEM_DESELECTED(LIST_CTRL, DeviceListCtrl::OnDeselected)
	EVT_MENU(LIST_SET_ID, DeviceListCtrl::OnSetID)
	EVT_MENU(LIST_UPDATE_FW, DeviceListCtrl::OnUpdateFirmware)
	EVT_MENU(LIST_UPDATE_KERNEL_DRIVER, DeviceListCtrl::OnUpdateKernelDriver)
END_EVENT_TABLE()

using namespace mvIMPACT::acquire;
using namespace std;

//-----------------------------------------------------------------------------
int wxCALLBACK ListCompareFunction( long item1, long item2, long column )
//-----------------------------------------------------------------------------
{
	DeviceManager devMgr;
	switch( column )
	{
	case lcFamily:
		return devMgr[item1]->family.read().compare( devMgr[item2]->family.read() );
	case lcProduct:
		return devMgr[item1]->product.read().compare( devMgr[item2]->product.read() );
	case lcSerial:
		return devMgr[item1]->serial.read().compare( devMgr[item2]->serial.read() );
	case lcState:
		return devMgr[item1]->state.readS().compare( devMgr[item2]->state.readS() );
	case lcFWVersion:
		return devMgr[item1]->firmwareVersion.read() - devMgr[item2]->firmwareVersion.read();
	case lcDeviceID:
		return devMgr[item1]->deviceID.read() - devMgr[item2]->deviceID.read();
	default:
		return 0;
	}
}

//-----------------------------------------------------------------------------
DeviceListCtrl::DeviceListCtrl(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style, DeviceConfigureFrame* pParentFrame )
    : wxListCtrl(parent, id, pos, size, style), m_pParentFrame(pParentFrame), m_selectedItemID(-1)  {}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
void DeviceListCtrl::OnActivated( wxListEvent& )
//-----------------------------------------------------------------------------
{
	if( m_pParentFrame )
	{
		m_pParentFrame->ActivateDeviceInPropView( m_selectedItemID );
	}
}

//-----------------------------------------------------------------------------
void DeviceListCtrl::OnColClick( wxListEvent& event )
//-----------------------------------------------------------------------------
{
	SortItems( ListCompareFunction, event.GetColumn() );   
}

//-----------------------------------------------------------------------------
void DeviceListCtrl::OnSelected( wxListEvent& event )
//-----------------------------------------------------------------------------
{
	m_selectedItemID = GetItemData( event.m_itemIndex );
	if( m_pParentFrame )
	{
		m_pParentFrame->UpdateMenu( m_selectedItemID );
	}
}

//-----------------------------------------------------------------------------
void DeviceListCtrl::OnDeselected( wxListEvent& /*event*/ )
//-----------------------------------------------------------------------------
{
	m_selectedItemID = -1;
	if( m_pParentFrame )
	{
		m_pParentFrame->UpdateMenu( m_selectedItemID );
	}
}

//-----------------------------------------------------------------------------
void DeviceListCtrl::OnItemRightClick( wxListEvent& event )
//-----------------------------------------------------------------------------
{
	wxMenu menu("");
	menu.Append( LIST_SET_ID, wxT("&Set ID") );
	menu.Append( LIST_UPDATE_FW, wxT("&Update firmware") );
	if( m_pParentFrame &&
		( m_selectedItemID >= 0 ) && 
		( static_cast<int>(m_pParentFrame->GetDeviceManager().deviceCount()) > m_selectedItemID ) )
	{
		string kernelDriverName;
		bool boNewerDriverAvailable;
		if( SupportsKernelDriverFeature( m_pParentFrame->GetDeviceManager().getDevice( GetItemData( event.m_itemIndex ) ), kernelDriverName, boNewerDriverAvailable ) )
		{
			wxMenuItem* pMI = menu.Append( LIST_UPDATE_KERNEL_DRIVER, wxT("Update &kernel driver") );
			pMI->Enable( boNewerDriverAvailable );

		}
	}
	PopupMenu( &menu, event.GetPoint() );
}

//-----------------------------------------------------------------------------
void DeviceListCtrl::OnSetID( wxCommandEvent& /*event*/)
//-----------------------------------------------------------------------------
{
	if( m_pParentFrame )
	{
		m_pParentFrame->SetID( m_selectedItemID );
	}
}

//-----------------------------------------------------------------------------
void DeviceListCtrl::OnUpdateFirmware( wxCommandEvent& /*event*/)
//-----------------------------------------------------------------------------
{
	if( m_pParentFrame )
	{
		m_pParentFrame->UpdateFirmware( m_selectedItemID );
	}
}

//-----------------------------------------------------------------------------
void DeviceListCtrl::OnUpdateKernelDriver( wxCommandEvent& /*event*/ )
//-----------------------------------------------------------------------------
{
	if( m_pParentFrame )
	{
		m_pParentFrame->UpdateKernelDriver( m_selectedItemID );
	}
}

BEGIN_EVENT_TABLE(LogOutputListCtrl, wxListCtrl)
	EVT_LIST_COL_CLICK(LIST_CTRL, LogOutputListCtrl::OnColClick)
	EVT_LIST_COL_RIGHT_CLICK(LIST_CTRL, LogOutputListCtrl::OnColumnRightClick )
	EVT_LIST_ITEM_SELECTED(LIST_CTRL, LogOutputListCtrl::OnSelected)
	EVT_LIST_ITEM_RIGHT_CLICK(LIST_CTRL, LogOutputListCtrl::OnItemRightClick)
	EVT_LIST_ITEM_DESELECTED(LIST_CTRL, LogOutputListCtrl::OnDeselected)
	EVT_MENU(LIST_CONFIGURE, LogOutputListCtrl::OnModifyItem)
	EVT_MENU(LIST_ADD, LogOutputListCtrl::OnAddItem)
	EVT_MENU(LIST_DELETE, LogOutputListCtrl::OnDeleteItem)
	EVT_MENU(LIST_DELETE_ALL, LogOutputListCtrl::OnDeleteAll)
END_EVENT_TABLE()

//-----------------------------------------------------------------------------
LogOutputListCtrl::LogOutputListCtrl(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style, LogOutputHandlerDlg* pParent )
    : wxListCtrl(parent, id, pos, size, style), m_pParent(pParent), m_selectedItemID(-1)  {}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnColClick( wxListEvent& event )
//-----------------------------------------------------------------------------
{
	//SortItems( DebugListCompareFunction, event.GetColumn() );   
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnColumnRightClick( wxListEvent& event )
//-----------------------------------------------------------------------------
{
	ShowPopup( event );
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnSelected( wxListEvent& event )
//-----------------------------------------------------------------------------
{
	m_selectedItemID = event.m_itemIndex;
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnDeselected( wxListEvent& /*event*/ )
//-----------------------------------------------------------------------------
{
	m_selectedItemID = -1;
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnItemRightClick( wxListEvent& event )
//-----------------------------------------------------------------------------
{
	ShowPopup( event );
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnModifyItem( wxCommandEvent& )
//-----------------------------------------------------------------------------
{
	m_pParent->ConfigureLogger( m_selectedItemID );
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnAddItem( wxCommandEvent& )
//-----------------------------------------------------------------------------
{
	m_pParent->InsertItem( m_selectedItemID );
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnDeleteItem( wxCommandEvent& )
//-----------------------------------------------------------------------------
{
	m_pParent->DeleteItem( m_selectedItemID );
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::OnDeleteAll( wxCommandEvent& )
//-----------------------------------------------------------------------------
{
	m_selectedItemID = -1;
	m_pParent->DeleteList();
	DeleteAllItems();
}

//-----------------------------------------------------------------------------
void LogOutputListCtrl::ShowPopup( wxListEvent& event )
//-----------------------------------------------------------------------------
{
	wxMenu menu("");
	if( m_selectedItemID != -1 )
	{
		menu.Append( LIST_CONFIGURE, wxT("&Configure item") );
	}
	menu.Append( LIST_ADD, wxT("&Add item") );
	if( m_selectedItemID != -1 )
	{
		menu.Append( LIST_DELETE, wxT("&Delete item") );
	}
	menu.Append( LIST_DELETE_ALL, wxT("C&lear list") );
	PopupMenu(&menu, event.GetPoint());
}
