/*	XGListControl.cpp
 *
 *		This is the control. This contains two scroll bars and the
 *	scroll view object
 */

/*  YAAF - Yet another application framework
 *  Copyright (C) 1997, 1998 William Edward Woody
 *  
 *  This library is free software; you can redistribute it
 *  and/or modify it under the terms of the GNU Library
 *  General Public License as published by the Free Software
 *  Foundation; either version 2 of the License, or 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 MERCHANTABIILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE. See the GNU Library General Public License for
 *  more details.
 *  
 *  You should have received a copy of the GNU Library General
 *  Public License along with this library; if not, write to the
 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *  Boston, MA 02111-1307, USA.
 *  
 *  To contact the author, either e-mail me at woody@pandawave.com, 
 *	or write to
 *  
 *          William Edward Woody
 *          In Phase Consulting
 *          1545 Ard Eevin Avenue
 *          Glendale, CA 91202
 *
 *	Or visit us on the web at http://www.pandawave.com
 */

#include <XConfig.h>			// must be first to optimize compile on MSVC++
#include <XList.h>
#include <XDraw.h>

/************************************************************************/
/*																		*/
/*	Construction/Destruction											*/
/*																		*/
/************************************************************************/

/*	@F"XGListControl::XGListControl" @I
 *
 *		Create the list controls
 */

XGListControl::XGListControl(XGOwner *owner, XGArgStream &s) :
	XGScrollView(owner,s), fList(sizeof(bool))
{
	fView = new XGListView(this);
	
	fUpdate = true;
	fNeedUpdate = false;
	
	fMultiSelect = s.ReadBoolean();
	fFont = XGFont::LoadFont(s.ReadInteger());
}

/*	@F"XGListControl::~XGListControl" @I
 *
 *		Delete this.
 */

XGListControl::~XGListControl()
{
}

/************************************************************************/
/*																		*/
/*	Control List Management												*/
/*																		*/
/************************************************************************/

/*	@F"XGListControl::GetItem" @I
 *
 *		Get the specified item in a zero-based index
 */

void XGListControl::GetItem(long index, char *data) const
{
	fList.GetString(index,data);
}

/*	@F"XGListControl::Length" @I
 *
 *		# items in me
 */

long XGListControl::Length() const
{
	return fList.GetNumStrings();
}

/*	@F"XGListControl::Insert" @I
 *
 *		Insert this item
 */

void XGListControl::Insert(long index, const char *buffer)
{
	fList.Insert(index,buffer);
	
	if (fUpdate) {
		fView->InvalView();
		fView->CalcResize();
	} else {
		fNeedUpdate = true;
	}
}

/*	@F"XGListControl::Delete" @I
 *
 *		Delete this item
 */

void XGListControl::Delete(long index)
{
	fList.Delete(index);
	
	if (fUpdate) {
		fView->InvalView();
		fView->CalcResize();
	} else {
		fNeedUpdate = true;
	}
}

/*	@F"XGListControl::DeleteAll" @I
 *
 *		Delete all items
 */

void XGListControl::DeleteAll(void)
{
	fList.DeleteAll();
	
	if (fUpdate) {
		fView->InvalView();
		fView->CalcResize();
	} else {
		fNeedUpdate = true;
	}
}

/*	@F"XGListControl::SetUpdate" @I
 *
 *		Set the update
 */

void XGListControl::SetUpdate(bool update)
{
	if (fUpdate == update) return;

	if (update && !fUpdate) {
		if (fNeedUpdate) {
			fView->InvalView();
			fView->CalcResize();
			fNeedUpdate = false;
		}
	}
	fUpdate = update;
}

/*	@F"XGListControl::GetSelect" @I
 *
 *		Get the selection state
 */

bool XGListControl::GetSelect(long index)
{
	bool retval;
	
	if (index < 0) return false;
	if (index >= Length()) return false;
	
	fList.GetExtra(index,&retval);
	return retval;
}

/*	@F"XGListControl::SetSelect" @I
 *
 *		Set the selection state
 */

void XGListControl::SetSelect(long index, bool state)
{
	long i,len;
	bool b;
	bool ob;
	
	len = Length();
	if (index < 0) return;
	if (index >= len) return;
	
	/*
	 *	Change the state, redrawing the approriate lines
	 */
	
	fList.GetExtra(index,&ob);
	if (ob == state) return;
	if (!fMultiSelect && (state == true)) {
		for (i = 0; i < len; i++) {
			b = (index == i) ? true : false;
			fList.GetExtra(i,&ob);
			if (ob != b) {
				fList.SetExtra(i,&b);
				fView->RedrawLine(i);
			}
		}
	} else {
		if (ob != state) {
			fList.SetExtra(index,&state);
			fView->RedrawLine(index);
		}
	}
}

/*	@F"XGListControl::ClearSelect" @I
 *
 *		Clear the selection state for everything
 */

void XGListControl::ClearSelect(void)
{
	long i,len;
	
	len = Length();
	for (i = 0; i < len; i++) SetSelect(i,false);
}

/*	@F"XGListControl::GetValue" @I
 *
 *		Useful for single selection stuff; this returns the index
 *	of the first selected item, or -1 if none are selected
 */

long XGListControl::GetValue()
{
	long i,len;
	
	len = Length();
	for (i = 0; i < len; i++) {
		if (GetSelect(i)) return i;
	}
	return -1;
}

/*	@F"XGListControl::SetValue" @I
 *
 *		Set only one selected item. Even if multiple selection is
 *	enabled
 */

void XGListControl::SetValue(long value)
{
	long i,len;
	
	len = Length();
	for (i = 0; i < len; i++) {
		SetSelect(i,(value == i));
	}
	fView->ScrollInRange(value);
}
