/******************************************************************************
 *
 * Copyright (c) 1999	TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *	Style.cpp
 *
 *****************************************************************************/

// SOL++2000
// 1999.09.25 Modified
// 2000.02.18


#include <sol\ApplicationView.h>
#include <sol\PaintDC.h>
#include <sol\ListBox.h>
#include <sol\PushButton.h>
#include <sol\ClientDC.h>
#include <sol\Font.h>
#include <sol\TextField.h>

class AppView :public ApplicationView {
	static Arg  styles[];
	static Arg  exStyles[];

	PushButton* create;
	PushButton* destroy;
	TextField*	textField;
	View*       view;
	Font*		font;
	ListBox*  stylesList;
	ListBox*  selList;
	ListBox*  windows;
	ListBox*  selExList;
	long	size(Event& event);
	void	selected(Action& action);
	void	exSelected(Action& action);
	void	removeStyle(Action& action);
	void	removeExStyle(Action& action);
	DWORD   getStyle(char* text);
	DWORD   getExStyle(char* text);
	void	createView(Action& action);
  public:
	AppView(Application& applet, const char* label, Args& args);
	~AppView();
};


Arg AppView::styles[] = {
	"WS_BORDER",		WS_BORDER,
	"WS_CAPTION",		WS_CAPTION,
	"WS_CHILD",			WS_CHILD,
	"WS_DLGFRAME",		WS_DLGFRAME,
	"WS_HSCROLL",		WS_HSCROLL,
	"WS_ICONIC",		WS_ICONIC,
	"WS_MAXIMIZE",		WS_MAXIMIZE,
	"WS_MAXIMIZEBOX",	WS_MAXIMIZEBOX,
	"WS_MINIMIZE",		WS_MINIMIZE,
	"WS_MINIMIZEBOX",	WS_MINIMIZEBOX,
	"WS_OVERLAPPED", 	WS_OVERLAPPED,
	"WS_OVERLAPPEDWINDOW",	WS_OVERLAPPEDWINDOW,
	"WS_POPUP",		WS_POPUP,
	"WS_POPUPWINDOW",	WS_POPUPWINDOW,
	"WS_SYSMENU",		WS_SYSMENU,
	"WS_THICKFRAME",	WS_THICKFRAME,
	"WS_VISIBLE",		WS_VSCROLL,
	"WS_VSCROLL",		WS_VSCROLL,
};

Arg AppView::exStyles[] = {
	"WS_EX_DLGMODALFRAME"	 ,WS_EX_DLGMODALFRAME,
	"WS_EX_NOPARENTNOTIFY" ,WS_EX_NOPARENTNOTIFY,
	"WS_EX_TOPMOST"        ,WS_EX_TOPMOST,
	"WS_EX_ACCEPTFILES"    ,WS_EX_ACCEPTFILES,
	"WS_EX_TRANSPARENT"    ,WS_EX_TRANSPARENT,

//Version >=4.0 
//	WS_EX_MDICHILD          
	"WS_EX_TOOLWINDOW"     ,WS_EX_TOOLWINDOW,   
	"WS_EX_WINDOWEDGE"     ,WS_EX_WINDOWEDGE,   
	"WS_EX_CLIENTEDGE"     ,WS_EX_CLIENTEDGE,   
	"WS_EX_CONTEXTHELP"    ,WS_EX_CONTEXTHELP,   

	"WS_EX_RIGHT"          ,WS_EX_RIGHT,   
	"WS_EX_LEFT"           ,WS_EX_LEFT,   
	"WS_EX_RTLREADING"     ,WS_EX_RTLREADING,   
	"WS_EX_LTRREADING"     ,WS_EX_LTRREADING,   
	"WS_EX_LEFTSCROLLBAR"  ,WS_EX_LEFTSCROLLBAR,   
	"WS_EX_RIGHTSCROLLBAR" ,WS_EX_RIGHTSCROLLBAR,   

	"WS_EX_CONTROLPARENT"  ,WS_EX_CONTROLPARENT,   
	"WS_EX_STATICEDGE"     ,WS_EX_STATICEDGE,   
	"WS_EX_APPWINDOW"      ,WS_EX_APPWINDOW,   
};

AppView::AppView(Application& applet, const char* label, Args& args)
	:ApplicationView(applet, label, args)
{
	Args ar;  

	ClientDC dc(this);
	UINT charSet = dc.getTextCharsetInfo(NULL);
	ar.reset();
	ar.set(XmNheight, (-12));
	ar.set(XmNcharSet, (ulong)charSet);
	font = new Font(ar);
	
	ar.reset();
	textField = new TextField(this, "Create", ar);
	textField -> setFont(font);

	ar.reset();
	create = new PushButton(this, "Create", ar);
	create -> addCallback(XmNactivateCallback, this,
		(Callback)&AppView::createView, NULL);
	create -> setFont(font);

	ar.reset();
	ar.set(XmNstyle, (ulong)WS_VSCROLL|LBS_NOINTEGRALHEIGHT);
	stylesList  = new ListBox(this, "", ar);
	stylesList -> setFont(font);

	for(int i = 0; i< XtNumber(styles); i++) {
		stylesList -> addString(styles[i].name);
	}
	stylesList -> addCallback(XmNselChangeCallback, this,
		(Callback)&AppView::selected, NULL);

	ar.reset();
	ar.set(XmNstyle, (ulong)WS_VSCROLL|LBS_NOINTEGRALHEIGHT);
	selList = new ListBox(this, "", ar);
	selList -> setFont(font);
	selList -> addCallback(XmNselChangeCallback, this,
		(Callback)&AppView::removeStyle, NULL);

	ar.reset();
	ar.set(XmNstyle, (ulong)WS_VSCROLL|LBS_NOINTEGRALHEIGHT);

	windows  = new ListBox(this, "", ar);
	windows -> setFont(font);

	for(int n = 0; n< XtNumber(exStyles); n++) {
		windows -> addString(exStyles[n].name);
	}
	windows -> addCallback(XmNselChangeCallback, this,
		(Callback)&AppView::exSelected, NULL);

	ar.reset();
	ar.set(XmNstyle, (ulong)WS_VSCROLL|LBS_NOINTEGRALHEIGHT);
	selExList  = new ListBox(this, "", ar);
	selExList -> setFont(font);
	selExList -> addCallback(XmNselChangeCallback, this,
		(Callback)&AppView::removeExStyle, NULL);

	view = NULL;
}


AppView::~AppView()
{
	delete stylesList;
	delete selList;
	delete windows;
	delete selExList;
}


void AppView::selected(Action& action)
{
	char* text = stylesList -> getCurText();
	if(text) {
		selList -> addString(text);
		delete text;
	}
}

void AppView::exSelected(Action& action)
{
	char* text = windows -> getCurText();
	if(text) {
		selExList -> addString(text);
		delete text;
	}
}

//
void AppView::removeStyle(Action& action)
{	
	int id = selList -> getCurSel();
	if(id !=LB_ERR) {
		selList -> deleteString(id);
	}
}

void AppView::removeExStyle(Action& action)
{
	int id = selExList -> getCurSel();
	if(id !=LB_ERR) {
		selExList -> deleteString(id);
	}
}

DWORD AppView::getStyle(char* text) 
{
	DWORD style = NULL;
	for(int i = 0; i<XtNumber(styles); i++) {
		if(strcmp(styles[i].name, text) == 0) {
			style = (DWORD)styles[i].value;
			break;
		}
	}
	return style;
}


DWORD AppView::getExStyle(char* text) 
{
	DWORD style = NULL;
	for(int i = 0; i<XtNumber(exStyles); i++) {
		if(strcmp(exStyles[i].name, text) == 0) {
			style = (DWORD)exStyles[i].value;
			break;
		}
	}
	return style;
}

void AppView::createView(Action& action)
{
	DWORD exStyle = NULL;
	DWORD style = NULL;
	int num = selExList -> getCount();
	char text[128];
	for(int i = 0; i<num; i++) {
			selExList -> getText(i, text);		
			exStyle |= getExStyle(text);	
	}

	num = selList -> getCount();
	if(num > 0) {
		for(int i = 0; i<num; i++) {
			selList -> getText(i, text);		
			style |= getStyle(text);	
		}

		Args ar;
		ar.set(XmNexStyle, exStyle);
		ar.set(XmNstyle, style);
		ar.set(XmNx,   20);
		ar.set(XmNy,   20);
		ar.set(XmNwidth, 400);
		ar.set(XmNheight,200);
		if(view) delete view;

		view = new View(this, "Window", ar);
		view -> setLocation(20, 20);
		view -> setSize(400, 200);
		view -> reshape(20, 20, 400, 200);
		view -> show(SW_SHOW);
	}
}


long AppView::size(Event& event)
{
	int w, h;
	event.getSize(w, h);
	Dimension d;
	create->getPreferredSize(d);
	create->setLocation(10, 4);
	Dimension td;
	textField ->getPreferredSize(td);
	textField -> reshape(d.getWidth()+20, 4, w-
						d.getWidth()-30, td.getHeight());

	stylesList -> reshape(2, 2+40, w/2 -1, h/2-1-40);
	selList -> reshape(w/2+1, 2+40, w/2 -1, h/2 -1-40);
	windows -> reshape(2, h/2+20, w/2-2, h/2-1-40);
	selExList -> reshape(w/2, h/2+20, w/2-2, h/2-1-40);

	return NULL;
}


void	Main(int argc, char** argv)
{
	const char* appClass = "Window Style";
	Application applet(appClass, argc, argv);

	Args args;
	args.set(XmNbackground, (ulong)(COLOR_BTNFACE+1));
	AppView appView(applet, appClass, args);
	appView.realize();

	applet.run();
}

