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


#include <sol\Directory.h>

#include "SolWebServer.h"
#include "HTTPListener.h"
#include "HTTPCommunicator.h"
#include "resource.h"


SolWebServer::SolWebServer(Application& applet, const char* name, Args& args)
	:ApplicationView(applet, name, args)
{
	version = "SolWebServer 1.0";
//	setText((const char*)version);

    Args ar;
	ar.set(XmNheight, -12);
	font = new Font(ar);

	ar.reset();
    text = new ScrolledRichText(this, "", ar);
	text -> setFont(font);
	text -> exLimitText(100*1000);	//100KB
	add(text);

    addCallback(XmNmenuCallback, IDM_START, this, (Callback)&SolWebServer::start, null);
    addCallback(XmNmenuCallback, IDM_STOP, this, (Callback)&SolWebServer::stop, null);
    addCallback(XmNmenuCallback, IDM_CLEAR, this, (Callback)&SolWebServer::clear, null);
    addCallback(XmNmenuCallback, IDM_EXIT, this, (Callback)&SolWebServer::terminate, null);
	addCallback(XmNmenuCallback, IDM_SETUP, this,(Callback)&SolWebServer::setup, null);

	addEventHandler(WM_CLOSE, this, (Handler)&SolWebServer::close, NULL);


	restorePlacement();

	setProfile("SolWebServer.conf");

	ar.reset();
	ar.set(XmNwidth, 300);
	ar.set(XmNheight, 200);
	ar.set(XmNstyle, (ulong)WS_THICKFRAME);
	configDialog = new ConfigDialog(this, "Configuration", ar);
	configDialog -> addOkCallback(this, (Callback)&SolWebServer::updateConfiguration);

	thread = new HTTPListener(this);
    thread -> start();

}


void SolWebServer::start(Action& action)
{
	stop(action);

	thread = new HTTPListener(this);
    thread -> start();

	StatusBar* statusbar = getStatusBar();
	statusbar -> setText(0, 0, "Running");
	char buffer[256];
	clear(action);

	printf("[SolWebserver restarted]\r\n");
	
	sprintf(buffer, "PORT: %d  DOCUMENT: %s", port, (const char*)docRoot);
	statusbar -> setText(1, SBT_POPOUT, buffer);
}

void SolWebServer::stop(Action& action)
{
	if (thread) {
		thread ->stop();
		// 1999.08.23 Added the following line.
		thread -> wait();
		delete thread;
		thread = null;
		StatusBar* statusbar = getStatusBar();
		statusbar -> setText(0, 0, "Stopped");

	}
}

void SolWebServer::setProfile(const char* file)
{
	docRoot = "";
	port    = 80;
	cgiRoot = "";

	profile = new Profile("SolWebServer.conf");
	port = (unsigned short)profile->get("SolWebServer", "port", 80);

	char doc[256];
	char windir[256];
	::GetWindowsDirectory(windir, sizeof(windir));
	docRoot = windir;

	profile -> get("Document", "root", windir, doc, sizeof(doc));
	docRoot = doc;
	profile -> get("Document", "cgi",  windir, doc, sizeof(doc));
	cgiRoot = doc;

	Printf("Port %d\r\n", port);
	Printf("Root %s\r\n", (const char*)docRoot);
	Printf("CGI  %s\r\n", (const char*)cgiRoot);

	char buffer1[100];
	char buffer2[256];

	sprintf(buffer1, "Running");
	sprintf(buffer2, "PORT: %d  DOCUMENT: %s", port, (const char*)docRoot);
	StatusBar* statusbar = getStatusBar();
	statusbar -> setParts(2, sizeArray);
	statusbar -> setText(0,  0, buffer1);
	statusbar -> setText(1, SBT_POPOUT, buffer2);
}

		
SolWebServer::~SolWebServer()
{
	delete profile;
    delete thread;
    delete text;
	delete configDialog;
	delete font;
}


void SolWebServer::setup(Action& action)
{
	POINT p;
	getCursorPos(&p);
	int w, h;
	configDialog -> getSize(w, h);
	configDialog -> reshape(p.x, p.y, w, h);
	configDialog -> setPort(port);
	configDialog -> setDocumentRoot((const char*)docRoot);
	configDialog -> setCGIRoot((const char*)cgiRoot);

	configDialog -> popup(action);
}


void SolWebServer::updateConfiguration(Action& action)
{
	unsigned short p = (unsigned short)configDialog -> getPort();
	char path1[256];
	char path2[256];

	configDialog -> getDocumentRoot(path1, sizeof(path1)-1);
	configDialog -> getCGIRoot(path2, sizeof(path2) -1);

	Directory dir;
	if (p <=0 || p >65000) {
		showMessageDialog("Error", "Invalid port number.", MB_OK);	
		return;
	}

	if (dir.isExistent(path1) == False) {
		showMessageDialog("Error", "Document root path does not exist.", MB_OK);	
		return;
	}
	if (dir.isExistent(path2) == False) {
		showMessageDialog("Error", "CGI root path does not exist.", MB_OK);	
		return;
	}

	port = p;
	docRoot = path1;
	cgiRoot = path2;

	profile -> set("SolWebServer", "port", port);
	profile -> set("Document", "root", (char*)docRoot);
	profile -> set("Document", "cgi",  (char*)cgiRoot);

	Printf("PORT: %d  DOCUMENT: %s\r\n", port, (const char*)docRoot);
	configDialog -> popdown(action);

	//clear(action);
	start(action);
	//append("[SolWebServer restarted]\r\n");
}


void SolWebServer::clear(Action& action)
{
    text -> clear();
}


void SolWebServer::terminate(Action& a)
{
	// 1999.08.14
	if (thread) {
		thread -> stop();

		thread -> kill();
	}
	savePlacement();

    exit(a);
}


void SolWebServer::append(const char* string)
{
	if (text->getTextLength() >=100*1000) {
		text -> clear();
	}
    text -> append(string);
	text -> scrollCaret();
}


void SolWebServer::printf(const char* format,...)
{
	char buffer[1024];

	va_list pos;
	va_start(pos, format);
	vsprintf(buffer, format, pos);
	va_end(pos);

	append(buffer);
}


long SolWebServer::close(Event& event)
{
	savePlacement();
	return defaultProc(event);
}


long SolWebServer::size(Event& event) 
{
	ApplicationView::size(event);
	int w, h;
	StatusBar* statusbar = getStatusBar();
	event.getSize(w, h);
	sizeArray[0] = w/4;
	sizeArray[1] = -1;

	statusbar->setParts(2, sizeArray);
	RECT r;
	statusbar->getWindowRect(&r);
	text -> reshape(0, 0, w,  h-(r.bottom-r.top));
	return 0;
}


// Program entry point!

void	Main(int argc, char** argv)
{
	const char* name = "SolWebServer";
	Application applet(name, argc, argv);

	Args args;
	args.set(XmNbackground, (COLOR_BTNFACE+1));
	args.set(XmNdefaultStatusBar, TRUE);
	args.set(XmNmenuName, name);
	SolWebServer solWebServer(applet, name, args);
	solWebServer.realize();
	applet.run();
}

