//
//	Copyright © 2006 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#include "StdHeaders.h"

#include "ListBoxCtrl.h"

#include "Dialog.h"

using namespace VectorWorks::VWUI;

VWListBoxCtrl::VWListBoxCtrl(TControlID id)
: VWControl( id )
{
}

VWListBoxCtrl::~VWListBoxCtrl()
{
}

bool VWListBoxCtrl::CreateControl(VWDialog* pDlg, short widthInCharacters, short heightInLines/*=1*/)
{
	farrIndexToMarker.clear();
	::GS_CreateListBox( gCBP, pDlg->GetControlID(), fControlID, widthInCharacters, heightInLines );
	return VWControl::CreateControl( pDlg );
}

void VWListBoxCtrl::DeleteAllItems()
{
	::GS_DeleteAllItems( gCBP, fpParentDlg->GetControlID(), fControlID );
	farrIndexToMarker.clear();
}

void VWListBoxCtrl::AddItem(const TXString& itemText, size_t insertAt /* = (size_t)-1*/, long marker /* = 0*/)
{
	if ( insertAt == (size_t) -1 )
		insertAt		= this->GetItemsCount();

	Str255		szText;
	itemText.CopyInto( szText );

	::GS_AddChoice( gCBP, fpParentDlg->GetControlID(), fControlID, szText, DemoteTo<short>( kVStanev, insertAt ) );

	// set marker for this item
	if ( insertAt >= farrIndexToMarker.size() ) {
		// make sure we have enough space for the marker of this element
		farrIndexToMarker.resize( insertAt + 1 );
	}

	farrIndexToMarker[ insertAt ]	= marker;
}

void VWListBoxCtrl::RemoveItem(size_t itemIndex)
{
	DSTOPIF( itemIndex >= this->GetItemsCount(), (kVStanev, "Deleting item = %d that doesn't exist in VWListBoxCtrl", itemIndex) );

	ASSERTN( kVStanev, itemIndex < farrIndexToMarker.size() );
	if ( itemIndex < farrIndexToMarker.size() ) {
		farrIndexToMarker.erase( farrIndexToMarker.begin() + itemIndex );
	}
	::GS_RemoveChoice( gCBP, fpParentDlg->GetControlID(), fControlID, DemoteTo<short>( kVStanev, itemIndex ) );
}

size_t VWListBoxCtrl::GetItemsCount() const
{
	short	numItems	= 0;
	::GS_GetChoiceCount( gCBP, fpParentDlg->GetControlID(), fControlID, numItems );
	return (size_t) numItems;
}

size_t VWListBoxCtrl::GetItemIndex(const TXString& itemText) const
{
	GSStr255		szText;
	itemText.CopyInto( szText );

	short nItemIndex	= -1;
	::GS_GetChoiceIndex( gCBP, fpParentDlg->GetControlID(), fControlID, szText, nItemIndex );
	return (size_t) nItemIndex;
}

void VWListBoxCtrl::GetItemText(size_t itemIndex, TXString& outText) const
{
	GSStr255		str255;
	::GS_GetChoiceText( gCBP, fpParentDlg->GetControlID(), fControlID, DemoteTo<short>( kVStanev, itemIndex ), str255 );
	outText			= str255;
}

void VWListBoxCtrl::SetItemText(size_t itemIndex, const TXString& text)
{
	bool	bWasSelected	= this->GetSelectedIndex() == itemIndex;
	this->RemoveItem( itemIndex );
	this->AddItem( text, itemIndex );
	if ( bWasSelected ) {
		this->SelectIndex( itemIndex );
	}
}

long VWListBoxCtrl::GetItemMarker(size_t itemIndex) const
{
	long	marker	= 0;
	if ( itemIndex < farrIndexToMarker.size() ) {
		marker	= farrIndexToMarker[ itemIndex ];
	}

	return marker;
}

void VWListBoxCtrl::SetItemMarker(size_t itemIndex, long marker)
{
	if ( itemIndex < farrIndexToMarker.size() ) {
		farrIndexToMarker[ itemIndex ]	= marker;
	}
}

size_t VWListBoxCtrl::GetSelectedIndex() const
{
	short	nItemIndex	= -1;
	::GS_GetSelectedChoiceIndex( gCBP, fpParentDlg->GetControlID(), fControlID, nItemIndex );
	return (size_t) nItemIndex;
}

void VWListBoxCtrl::SelectIndex(size_t itemIndex)
{
	::GS_SelectChoice( gCBP, fpParentDlg->GetControlID(), fControlID, DemoteTo<short>( kVStanev, itemIndex ) );
}

long VWListBoxCtrl::GetSelectedItemMarker() const
{
	size_t	selIndex	= this->GetSelectedIndex();
	return this->GetItemMarker( selIndex );
}

bool VWListBoxCtrl::SelectItemWithMarker(long marker)
{
	bool		bOk			= false;
	size_t		markersCnt	= farrIndexToMarker.size();
	for(size_t i=0; i<markersCnt; i++) {
		const long&		thisMarker	= farrIndexToMarker[ i ];
		if ( thisMarker == marker ) {
			this->SelectIndex( i );
			bOk			= true;
			// continue to allow multiple selection -- if supported
			// or it will select the last item with the same marker - which is ok with us
		}
	}

	return bOk;
}

void VWListBoxCtrl::AddTabStop(size_t size)
{
	::GS_AddListBoxTabStop( gCBP, fpParentDlg->GetControlID(), fControlID, (short) size );
}

void VWListBoxCtrl::RemoveLastTabStop()
{
	::GS_RemoveListBoxTabStop( gCBP, fpParentDlg->GetControlID(), fControlID );
}


