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

// SOL++2000 Sample
// 2000/11/11

#include <sol\ApplicationView.h>
#include <sol\PushButton.h>
#include <sol\LabelGadget.h>
#include <sol\TextField.h>
#include <sol\Profile.h>
#include <sol\ScrolledRichText.h>
#include <sol\SocketStream.h>
#include <sol\Font.h>
#include <sol\ClientDC.h>
#include <sol\PaintDC.h>
#include <sol\stdio.h>
#include <sol\InetAddress.h>
#include <sol\URL.h>

#include "HTMLReader.h"
#include "ProxySetting.h"
#include "resource.h"


class HTMLViewer :public ApplicationView {
	int			textHeight;
	LabelGadget		urlLabel;
	TextField		urlField;
	Font			font;
	SocketStream*		sock;
	ScrolledRichText	sctext;
	HTMLReader*		reader;
	ProxySetting		proxySetting;
	const char*		proxyHost;
	int			proxyPort;

	void	setProxy(Action& action);
	void	popupProxySetting(Action& action);

	void	clear(Action& action);
	long	size(Event& event);
	long	close(Event& event);
	long	paint(Event& event);

	void	recv();
	void	startReader(Action& action);
	void	receive(const char* host, const char* path, unsigned short port);
	void	readFile(const char* fileName);
	

  public:
	HTMLViewer(Application& applet, const char* name, Args& args);
	~HTMLViewer();
};


HTMLViewer::HTMLViewer(Application& applet, const char* name, Args& args)
	:ApplicationView(applet, name, args)
{
	sock   = null;
	reader = null;

	int cx = ::GetSystemMetrics(SM_CXSCREEN);
	int fheight = -12;
	if(cx > 1024) {
		fheight = -16;
	}

	ClientDC dc(this);

	Args ar;
	ar.set(XmNheight, fheight);
	ar.set(XmNcharSet, (ulong)dc.getTextCharsetInfo(NULL));
	font.create(ar);

	HFONT prevFont = dc.select(&font);
	textHeight = dc.getTextHeight();
	dc.select(prevFont);

	ar.reset();
	ar.set(XmNstyle, (ulong)(WS_HSCROLL|WS_VSCROLL|WS_BORDER|ES_AUTOHSCROLL|\
		 ES_AUTOVSCROLL|ES_WANTRETURN|ES_LEFT|ES_MULTILINE));

	sctext.create(this, "", ar);
	sctext.setFont(font);
	RECT rc;
	rc.left = 0;
	rc.top  =0;
	rc.right = 120;
	rc.bottom = 200;

	sctext.setRect(&rc);
	sctext.limitText(100000);
	sctext.setReadOnly();

	sctext.addCallback(XmNmaxTextCallback, this,
		(Callback)&HTMLViewer::clear, NULL);

	ar.reset();
	urlLabel.create(this, "URL", ar);
	urlLabel.setFont(&font);

	ar.reset();
	urlField.create(this, "",   ar);
	urlField.setFont(font);
	urlField.addCallback(XmNactivateCallback, this,
		(Callback)&HTMLViewer::startReader, NULL);

	proxyHost = "";
	proxyPort = 8080;

	ar.reset();
	ar.set(XmNwidth, 300);
	ar.set(XmNheight, 180);
	proxySetting.create(this, "ProxySetting", ar);
	proxySetting.addOkCallback(this, (Callback)&HTMLViewer::setProxy);

	addCallback(XmNmenuCallback, IDM_CLEAR, this, 
		(Callback)&HTMLViewer::clear, NULL);
	addCallback(XmNmenuCallback, IDM_PROXY, this, 
		(Callback)&HTMLViewer::popupProxySetting, NULL);

	addCallback(XmNmenuCallback, IDM_EXIT, this, 
		(Callback)&HTMLViewer::exit, NULL);

	addEventHandler(WM_CLOSE, this, (Handler)&HTMLViewer::close, NULL);
	addEventHandler(WM_PAINT, this, (Handler)&HTMLViewer::paint, NULL);
}


HTMLViewer::~HTMLViewer() 
{
	delete sock;
	delete reader;
}


void HTMLViewer::clear(Action& action) 
{ 
	urlField.clear();
	sctext.clear(); 
}


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


void HTMLViewer::popupProxySetting(Action& action)
{
	if (proxyHost != null) {
		proxySetting.setHost(proxyHost);	
	}

	if (proxyPort >=0 && proxyPort < 65535) {
		proxySetting.setPort(proxyPort);
	}
	proxySetting.popup(action);
}


void HTMLViewer::setProxy(Action& action)
{
	const char* host = proxySetting.getHost();
	int         port = proxySetting.getPort();
	if (host != null && port >=0 && port< 65535) {
		proxySetting.popdown(action);
		proxyHost = host;
		proxyPort = port;
	}
}



void HTMLViewer::startReader(Action& action)
{
	// Termainte the previous reader thread.
	if (reader) {
		reader->kill();
		Printf("Terminated a previous reader thread.\r\n");
		Printf("Waiting the termination of the thread.\r\n");
		reader->wait();
		delete reader;
		reader = null;
	}

	char aurl[256];
	urlField.getText(aurl, sizeof(aurl));

	// Create an instance of HTMLReader thread.
	if (proxyHost != null && strlen(proxyHost) > 0 
		&& proxyPort >=0 && proxyPort < 65535) {
		reader = new HTMLReader(&sctext, aurl, proxyHost, proxyPort);
		
	} else {
		reader = new HTMLReader(&sctext, aurl);
	}

	sctext.clear();

	// Start the reader thread.
	reader->start();
}


long HTMLViewer::paint(Event& event) 
{
	PaintDC dc(this);
	urlLabel.draw(&dc);

	return 0;
}


long HTMLViewer::size(Event& event)
{
	int w, h;
	event.getSize(w, h);
	int y =  textHeight+8;
	int lw = textHeight*2;
	int top = 4;
	int m   = 4;
	urlLabel.setLocation(m, top);
	int ww, hh;

	urlLabel.getSize(ww, hh);
	urlField.reshape(ww+m+10, top, w-m*2-lw-10, y);

	sctext.reshape(0, top+y+m, w, h-top-y-m);

	return 0L;
}


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

	Args args;
	args.set(XmNclassName, appClass);
	args.set(XmNbackground, (COLOR_BTNFACE+1));

	HTMLViewer htmlViewer(applet, appClass, args);
	htmlViewer.realize();

	applet.run();	
}

