#include <string.h>
#include <Pandora TCP Server.h>

struct MyHTTPServerIOStream	:	public PHTTPServerIOStream
{
	MyHTTPServerIOStream(unsigned short port,PTCPAsyncNotifier* notifier);
	virtual	char	handleMethod(const char* method) throw(PErr);
};

struct FileMenu	:	public PMenu
{
	FileMenu();
	
	virtual	void	menuPrepare();
	virtual	void	handleMenuSelection(unsigned short item);
};

struct MyApplication	:	public PApplication
{
	FileMenu							fileMenu;
	PFileOStream						logFile;
	PTCPServer<MyHTTPServerIOStream>	httpServer;
	
	MyApplication();
	~MyApplication();
};

MyApplication* theApp = nil;

void main(void)
{
	try
	{
		theApp = new MyApplication;
		theApp->run();
	}
	catch(PErr err)
	{
		dout << "Error " << err << " was thrown and caught in main()!\n";
	}
	catch(...)
	{
		dout << "Some really weird error was caught in main() - it wasn't even a PErr!\n";
	}
	
	delete theApp;
}

MyHTTPServerIOStream::MyHTTPServerIOStream(unsigned short port,PTCPAsyncNotifier* notifier):
	PHTTPServerIOStream(port),
	PTCPStream(notifier)
{
}

char MyHTTPServerIOStream::handleMethod(const char* methodName) throw(PErr)
{
	// Log this request.
	theApp->logFile << *const_cast<PHTTPRequestHeader*>(getCurrentRequest());
	
	// Try to handle this method first
	if(!strncmp(methodName,"GET",3) || !strncmp(methodName,"HEAD",4))
	{
		char*	relPath = nil;
		char		sentHeader = false;
		
		try
		{
			relPath = new char[strlen(getURI()) + 22];
			strcpy(relPath,"Web Site:public_html");
			strcat(relPath,getURI());
			
			PFileDescriptor			fd(PConvertChars('/',':',relPath,relPath));
			
			// Open this file
			PFileIStream			istream(fd);
			
			// Send the HTTP header for this file
			sentHeader = true;
			sendDataHeader(istream.getEOS(),PGetMIMEType(istream.name()));
			
			// If this was a GET request, send the file too.
			if(!strncmp(methodName,"GET",3))
				PStream::pipe(istream,*this,istream.getEOS());
		}
		catch(PErr err)
		{
			if(!sentHeader)
			{
				try
				{
					// Some error occurred.  Try to send a message.
					sendErrorMessage(err,"An error occured while trying to transfer data on this stream.");
				}
				catch(...)
				{
				}
			}
		}
		catch(...)
		{
		}
		
		// Delete the pathname
		delete relPath;
		
		return true;
	}
	
	// We couldn't handle the method.  Maybe someone else can.
	return PHTTPServerIOStream::handleMethod(methodName);
}

FileMenu::FileMenu():
	PMenu("File")
{
	addMenuItem("Quit",'Q');
}

void FileMenu::menuPrepare()
{
}

void FileMenu::handleMenuSelection(unsigned short item)
{
	if(item == 1)
		theApp->quit();
}

MyApplication::MyApplication():
	logFile(PPutFileDescriptor('CWIE','TEXT',"Save web log as:","Log File")),
	httpServer(80)
{
}

MyApplication::~MyApplication()
{
}
