/******************************************************************************
 *
 * 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.
 *
 *
 *	ApplicationView.cpp
 *
 *****************************************************************************/

// SOL++2000

#include <sol\ApplicationView.h>
#include <sol\Profile.h>

long ApplicationView::size(Event& event)
{
	int	w, h;
	event.getSize(w, h);

	int	top = 0;
	if (toolBar) {
		toolBar -> send(event.getMessage(), 
			event.getWParam(), event.getLParam());
		top = toolBar -> getHeight();
	}

	if(statusBar) {
		statusBar -> send(event.getMessage(),
				event.getWParam(), event.getLParam());
		h = h - top - statusBar -> getHeight();
	}
	justifyScrollRange();
	layout(0, top, w, h);

	return 0L;
}


ApplicationView::ApplicationView(Application& applet, const char* name,
				Args& args)
	:Composite(NULL, name,
		args.set(XmNx,      (ulong)CW_USEDEFAULT)
		    .set(XmNy,      (ulong)CW_USEDEFAULT)
		    .set(XmNwidth,  (ulong)CW_USEDEFAULT)
		    .set(XmNheight, (ulong)CW_USEDEFAULT)
		    .set(XmNstyle,  (ulong)WS_OVERLAPPEDWINDOW)
		    .set(XmNclassName, "ApplicationView")),
	application(applet),
	menuBar(null),
	accel(null),
	toolBar(null),
	statusBar(null),
	defaultLayout(null)
{
	defaultLayout = new DefaultLayout();
	setLayout(defaultLayout);
	applet.setToplevel(this);

	ulong val;
	const char* menuName = name;
	if (args.get(XmNmenuName, &val)) {
		menuName = (const char*)val;
	}
	menuBar = new MenuBar(this, menuName);

	const char* accelName = name;
	if (args.get(XmNacceleratorName, &val)) {
		accelName = (const char*)val;
	}
	accel   = new Accelerator(accelName);

	Args ar;
	if (args.get(XmNdefaultToolBar)) {
		ulong id = args.get(XmNtoolBarBitmapID);
		ar.set(XmNtoolBarBitmapID,  id);
		toolBar = new ToolBar(this, "", ar);
	}
	if(args.get(XmNdefaultStatusBar)) {
		ar.reset();
		statusBar = new StatusBar(this, "", ar);	
	}
}

ApplicationView::~ApplicationView() 
{ 
	// Don't delete the application
	delete defaultLayout;
	delete accel;	
	delete menuBar; 
	delete toolBar;
	delete statusBar;
}
	

// For compatibility Oz++ class library on Motif.
void	ApplicationView::realize()
{
	int cmdShow = SW_SHOWNORMAL;
	
	cmdShow = application.getShowCommand();
	show(cmdShow);
}


Boolean	ApplicationView::translate(MSG* msg)
{

	HACCEL haccel = NULL;
	if(accel) haccel = accel->get();
	if(haccel && ::TranslateAccelerator(getWindow(), haccel, msg)) {
		return TRUE;
	}
	else {
		return FALSE;
	}
}


void ApplicationView::getClientRect(RECT* r)
{
	View::getClientRect(r);
	if(toolBar) {
			RECT rt;
			toolBar -> getClientRect(&rt);
			r->top = (rt.bottom - rt.top);			
	}
	if(statusBar) {
			RECT rs;
			statusBar -> getClientRect(&rs);
			r->bottom -= (rs.bottom - rs.top);			
	}
}


int	ApplicationView::showMessageDialog(const char* message, int flag)
{
	if(isIconic()) {
		show(SW_NORMAL);
	}
	char* path = new char[_MAX_PATH];
	::GetModuleFileName(NULL, path, _MAX_PATH);
	char* progname = strrchr(path, '\\');
	if(progname) {
		progname++;
	
		char* tail = strrchr(progname, '.');
		if(tail) {
			*tail = '\0';
		}
	}
	int rc = ::MessageBox(getWindow(), message, progname, flag);
	delete [] path;	
	return rc;
}


int ApplicationView::showMessageDialog(const char* title, const char* message, int flag)
{
	if(isIconic()) {
		show(SW_NORMAL);
	}
	return ::MessageBox(getWindow(), message, title,  flag);
}



// 1996.12.01 to-arai
void ApplicationView::wait(LONG interval) 
{
	DWORD startedTime = ::GetTickCount();
	while(::GetTickCount() - startedTime < (DWORD)interval){
		MSG msg;
		if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
	}
}



void ApplicationView::restorePlacement(const char* name)
{
	Profile profile(name);
	WINDOWPLACEMENT pl;
	memset(&pl, 0, sizeof(pl));
	pl.length = sizeof(pl); 

	int x, y, w, h;
	profile.getGeometry(&x, &y, &w, &h);

	RECT r;
	r.left     = x;
	r.right    = x+ w;
	r.top      = y;
	r.bottom   = y+h;
	pl.showCmd = SW_SHOWNORMAL; 
	pl.rcNormalPosition = r;

	if(x > 0 && y > 0) {
		setPlacement(&pl);
	}
}


void ApplicationView::savePlacement(const char* name)
{
	Profile profile(name);
	WINDOWPLACEMENT pl;

	//	memset(&pl, 0, sizeof(pl));
	pl.length = sizeof(pl); 

	getPlacement(&pl);
	RECT r = pl.rcNormalPosition;
	profile.setGeometry(&r);
}

