/*	XTextControls.h
 *
 *		Standard text controls
 */

/**********************************************************************

  YAAF is Copyright 1997-1999 by William Woody.

  Redistribution and use in source and binary forms, with or without 
  modification, are permitted provided that the following conditions 
  are met:

  Redistributions of source code must retain the above copyright notice, 
  this list of conditions and the following disclaimer.

  Neither the name of the copyright holder or other contributors may
  be used to promote products derived from this software without
  specific written prior permission.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
  SOFTWARE.
  
  Contact:   woody@alumni.caltech.edu
  Web page:  http://www.pandawave.com/yaaf/

**********************************************************************/

#ifndef PandaWave_XTEXTCONTROLS
#define PandaWave_XTEXTCONTROLS

#include <XConfig.h>
#include <XView.h>
#include <XEvent.h>
#include <XString.h>
#include <XHandle.h>
#include <XEditCore.h>

/************************************************************************/
/*																		*/
/*	Forwards															*/
/*																		*/
/************************************************************************/


class XGFont;
class XGDraw;
class XGEditCore;

/************************************************************************/
/*																		*/
/*	Internal structures													*/
/*																		*/
/************************************************************************/

/*	XGECharType
 *
 *		Enumeration of the character types I can type
 */

enum XGECharType {
	KXGEAnyChar = 0,
	KXGEAlphaNumeric = 1,					// letters and numbers only
	KXGEHexDigit = 2,						// hex digits only
	KXGENumeric = 3,						// numbers only
	KXGENumSign = 4,						// +/- and numbers
	KXGEFloating = 5						// +/-, numbers and '.'
};

/*$	XGSTextInitRecord
 *
 *		This contains the common initialization parameters to initialize
 *	a button
 */

struct XGSTextInitRecord {
	XGSViewInitRecord			v;
	char						text[256];
	short						font;				// font resource ID
};

/*$	XGSEditInitRecord
 *
 *		Edit initialization record
 */

struct XGSEditInitRecord {
	XGSTextInitRecord			v;
	
	bool						password;			// password field?
	bool						wordwrap;			// word wrap?
	bool						autoindent;			// Auto indent?
	bool						noframe;			// No frame?
	bool						editor;				// Main editor or field?
	long						tabstop;			// Tab stop?
	long						maxchars;			// max characters
	XGECharType					chartype;			// what can i type?
};

/************************************************************************/
/*																		*/
/*	Standard Classes													*/
/*																		*/
/************************************************************************/

/*$	XGStaticText
 *
 *		Standard static text control. I do this myself...
 */

class XGStaticText : public XGView {
	public:
								XGStaticText(XGView *parent, XGArgStream &init);
								XGStaticText(XGView *parent, XGSTextInitRecord &init);
		virtual					~XGStaticText();
		
		enum {
			kClassID = 'text'
		};
		
		/*
		 *	Standard behaviour routines
		 */
		
		void					DoDrawView(XRect);
		
		/*
		 *	Text hooks
		 */
		
		void					GetTitle(char *) const;
		void					SetTitle(const char *);

	private:
		void					Init(char *, short);
		
		short					SkipSpace(const char *, short);
		short					NextWord(const char *, short);
		short					CharWidth(XGDraw &, const char *, short);
		void					DrawLines(XGDraw &, const char *, short, short, short);

		XGFont					*fFontPtr;
		XGString				fString;
};


/*$	XGEditText
 *
 *		And this is my standard edit control
 */

class XGEditText : public XGView {
	public:
								XGEditText(XGView *parent, XGArgStream &init);
								XGEditText(XGView *parent, XGSEditInitRecord &init);
		virtual					~XGEditText();
		
		enum {
			kClassID = 'edit'
		};
		
		/*
		 *	Standard behaviour routines
		 */
		
		void					DoDrawView(XRect);
		void					DoActivate(bool);
		bool					DoMouseDown(XPoint,short);
		void					DoMouseMove(XPoint,short);
		void					DoMouseUp(XPoint,short);
		void					DoSizeView();
		void					Scroll(long,long);
		
		void					DoGainFocus();
		void					DoLoseFocus();
		
		/*
		 *	Dispatched messages
		 */
		
		DECLAREDISPATCH
		long					DoIdle(long, void *);
		long					DoGetMenuStatus(long, void *);
		long					DoMenuCommand(long, void *);
		long					DoKey(long, void *);

		/*
		 *	Text selection
		 */
		
		void					SetSelect(long, long);
		void					GetSelect(long *, long *);
		
		/*
		 *	Editing control
		 */
		
		XGECharType				GetCharType()
									{
										return fCharType;
									}
		void					SetCharType(XGECharType type)
									{
										fCharType = type;
									}
		long					GetMaxChars()
									{
										return fMaxChars;
									}
		void					SetMaxChars(long max = 0)
									{
										fMaxChars = max;
									}
		bool					GetPassword()
									{
										return fEditCore->GetPassword();
									}
		void					SetPassword(bool password)
									{
										fEditCore->SetPassword(password);
										RecalcScroll();
										InvalView();
									}
		bool					GetWordWrap()
									{
										return fEditCore->GetWordWrap();
									}
		void					SetWordWrap(bool flag)
									{
										fEditCore->SetWordWrap(flag);
										RecalcScroll();
										InvalView();
									}
		bool					GetAutoIndent()
									{
										return fEditCore->GetAutoIndent();
									}
		void					SetAutoIndent(bool flag)
									{
										fEditCore->SetAutoIndent(flag);
									}
		long					GetTabStop()
									{
										return fEditCore->GetTabStop();
									}
		void					SetTabStop(long tab)
									{
										fEditCore->SetTabStop(tab);
									}

		/*
		 *	Text Hooks. (This limits text to 256 characters.)
		 */
		
		void					GetTitle(char *) const;
		// phook: hack stuff so we can do stli editing easy
		long					GetTitleEx(char *text, long max_len ) const;

		void					SetTitle(const char *);
		
		/*
		 *	Text modification
		 */
		
		XGHandle				&GetTextHandle()
									{
										return fTextHandle;
									}
		void					SetTextHandle(XGHandle &x)
									{
										fTextHandle = x;
										fEditCore->RecalcLineStarts();
										RecalcScroll();
										InvalView();
									}
		void					UpdateTextHandle()
									{
										fEditCore->RecalcLineStarts();
										RecalcScroll();
										InvalView();
									}
		
		/*
		 *	Standard editor modifier hooks
		 */
		
		virtual bool			CanInsertKey(char);
		virtual bool			IsSpecialKey(char);
		virtual void			DrawTextFrame(XGDraw &, XRect);
		virtual bool			ValidateText(char *);
		
	private:
		void					Init(char *, short, XGSEditInitRecord &);

		XGFont					*fFontPtr;
		XGHandle				fTextHandle;
		XGEditCore				*fEditCore;

		bool					fNoFrame;
		long					fMaxChars;
		XGECharType				fCharType;
		
		void					RecalcScroll();
		void					InsertChar(char);
		void					DeleteChar();
};

/*$	XGGroupBox
 *
 *		Standard group box. This creates a group box which draws
 *	a rectangle around the view. On the Macintosh, I duplicate the
 *	functionality in the XGStaticText view; in Windows, I call
 *	up the correct view window
 */

class XGGroupBox : public XGView {
	public:
								XGGroupBox(XGView *parent, XGArgStream &init);
								XGGroupBox(XGView *parent, XGSTextInitRecord &init);
								~XGGroupBox();

		enum {
			kClassID = 'grou'
		};

		/*
		 *	Group box
		 */
		
		void					DoDrawView(XRect);
		
		/*
		 *	Text hooks
		 */
		
		void					GetTitle(char *) const;
		void					SetTitle(const char *);

	private:
		void					Init(char *, short);

		XGFont					*fFontPtr;
		XGString				fString;
};


#endif
