#include "XControl.h"
#include "XWebView.h"
#include "xmsgbox.h"
#include "webexwin.h"
#include "xstring.h"
#include "XDefHdl.h"

/*@ 
@class XWebView
@type overview
@symbol _
@remarks XWebView is a high-level control which gives you the functionality of a web-browser.
It uses the the WebExplorer-display capabilitys so you can use the EMail and News services
too.<P>
To use the control in your application:
<OL>
<LI>derive a class from XWebView
<LI>override the functions you need (eg. HandleError())
<LI>call Load() with the needed URL
<LI>done
</OL>
*/

class webDefHandler:public XDefaultHandler
{
		XWebView *web;
	public:
		webDefHandler(const XWindow * w, const XWebView * v):XDefaultHandler(w)
				{ web = (XWebView *) v; }
		BOOL HandleEvent(ULONG, void *, void *);
};


/*@ XWebView :: XWebView(const XWindow * owner, const XRect * rec, const USHORT id)
@remarks Constructs a web-control
@parameters <t 'ø' c=2>
				øXWindow * owner  øthe owner window
           øXRect * rect     ørectangle
           øUSHORT id        øthe window-ID
				</t>
*/
XWebView :: XWebView(const XWindow * owner, const XRect * rec, const USHORT id):XControl(rec, WS_VISIBLE, owner, "", WC_WXVIEW, id)
{
	WXDISPLAYOPTS opts;

	WXViewQueryDisplayOpts(winhandle, &opts, sizeof(opts));
	WXViewSetDisplayOpts(winhandle, &opts, sizeof(opts));
	webDefHandler *d = new webDefHandler(owner, this);
}


/*@ XWebView::SetOptions(const char *emailAddress, const char *newsServer)
@group misc
@remarks Setup options for EMail and News services.
@parameters  char * emailAddress  your email address<BR>
            char * newsServer    the news-server to use
*/
void XWebView::SetOptions(const char *emailAddress, const char *newsServer)
{
	WXNETWORKOPTS opts;

	WXViewQueryNetworkOpts(winhandle, &opts, sizeof(opts));

	if (emailAddress)
		strcpy(opts.szEmailAddress, emailAddress);
	if (newsServer)
		strcpy(opts.szNewsServer, newsServer);
	WXViewSetNetworkOpts(winhandle, &opts, sizeof(opts));
}


/*@ XWebView::Load(const char *url, const BOOL reload)
@group load data
@remarks Load data from the internet/intranet
@parameters char * url   full qualified URL<BR>
           BOOL reload   TRUE=do not use cached data, FALSE=use cache
@returns     LONG result
*/
LONG XWebView::Load(const char *url, const BOOL reload)
{
	return WXViewLoad(winhandle, (PCSZ) url, (reload ? WXLOAD_ANCHOR | WXLOAD_FORCERELOAD : WXLOAD_ANCHOR), NULL);
}



/*@ XWebView::GetDocTitle(XString * buffer)
@group misc
@remarks Get the title of the document.
@parameters XString * buffer   buffer to hold data.
@returns     BOOL result
*/
BOOL XWebView::GetDocTitle(XString * buffer)
{
	SHORT len = WXViewQueryDocTitleLen(winhandle);

	if (len <= 0)
		return FALSE;
	LONG res = (LONG) WXViewQueryDocTitle(winhandle, (PSZ) buffer->GetBuffer(len + 1), len);

	buffer->ReleaseBuffer(len);
	return (res ? FALSE : TRUE);
}


/*@ XWebView::GetDocAnchor(XString * buffer)
@group anchor
@remarks Get the anchor of the document.
@parameters XString * buffer   buffer to hold data.
@returns     BOOL result
*/
BOOL XWebView::GetDocAnchor(XString * buffer)
{
	SHORT len = WXViewQueryDocAnchorLen(winhandle);
	LONG res = (LONG) WXViewQueryDocAnchor(winhandle, (PSZ) buffer->GetBuffer(len + 1), len);

	buffer->ReleaseBuffer(len);
	return (res ? FALSE : TRUE);
}


/*@ XWebView::Search(const char *searchString, const XPoint * start, XPoint * resBuffer, const BOOL forward)
@group misc
@remarks Search a string in the document.
@parameters <t 'ø' c=2>
				øchar* string       østring to find.
           øXPoint * start     øpoint in document-coordinates to start
           øXPoint * buffer    øbuffer which will hold coordinates of the result
           øBOOL forward       øTRUE=search forward, FALSE=backward
				</t>
@returns     BOOL result
*/
BOOL XWebView::Search(const char *searchString, const XPoint * start, XPoint * resBuffer, const BOOL forward)
{
	WXPOS s, e;

	s.x = start->GetX();
	s.y = start->GetY();
	LONG opts = (forward ? WXSEARCH_FORWARD : WXSEARCH_BACKWARD);

	if (WXViewSearch(winhandle, opts, &s, &e, (PSZ) searchString) != 0)
		return FALSE;
	else
		resBuffer->Set(e.x, e.y);
	return TRUE;
}


/*@ XWebView::GetPos(const XPoint * mouse, XPoint * view)
@group misc
@remarks Calculate document-coordinates from window-coordinates (e.g. mouse-position).
@parameters XPoint * in        window-cordinates<BR>
           XPoint * buffer    bufer wich will hold the document-coordinates
@returns     LONG result
*/
BOOL XWebView::GetPos(const XPoint * mouse, XPoint * view)
{
	WXPOS pos;

	if (WXViewQueryPos(winhandle, mouse->GetX(), mouse->GetY(), &pos) != 0)
		return FALSE;
	else
		view->Set(pos.x, pos.y);
	return TRUE;
}


/*@ XWebView::SetAnchorState(const char *anchor, const LONG state)
@group anchor
@remarks Set the state of an anchor.
@parameters  <t 'ø' c=2>
				øchar * anchor     øname of the anchor
            øLONG state        østate to set:
										<t 'ø' c=1>
                                 øWEB_ANCHOR_DEFAULT
                                 øWEB_ANCHOR_VISITED
										</t>
				</t>
@returns     BOOL result
*/
BOOL XWebView::SetAnchorState(const char *anchor, const LONG state)
{
	if (WXViewSetAnchorState(winhandle, anchor, state) == 0)
		return TRUE;
	else
		return FALSE;
}


/*@ XWebView::GetAnchorState(const char *anchor, LONG & state)
@group anchor
@remarks Get the state of an anchor.
@parameters  <t 'ø' c=2>
				øchar * anchor     øname of the anchor
            øLONG& state       øbuffer for the state to the anchor, you may receive:
										<t 'ø' c=1>
                                 øWEB_ANCHOR_DEFAULT
                                 øWEB_ANCHOR_VISITED
										</t>
				</t>
@returns     BOOL result
*/
BOOL XWebView::GetAnchorState(const char *anchor, LONG & state)
{
	WXFLAGS flags;

	if (WXViewQueryAnchorState(winhandle, anchor, &flags) == 0)
	{
		state = flags;
		return TRUE;
	}
	else
		return FALSE;
}


/*@ XWebView::SetViewer(const char *MIMEType, const char *program)
@group MIME
@remarks Register a viewer for a specific MIME-type
@parameters char * MIME     type of MIME<BR>
           char * program  program to register.
@returns     BOOL result
*/
BOOL XWebView::SetViewer(const char *MIMEType, const char *program)
{
	WXVIEWER view;

	strcpy(view.szMIMEType, MIMEType);
	strcpy(view.szProgram, program);
	if (WXViewSetViewer(winhandle, &view, sizeof(view)) == 0)
		return TRUE;
	else
		return FALSE;
}


/*@ XWebView::GetViewer(const char *MIMEType, XString * program)
@group MIME
@remarks Get a viewer for a specific MIME-type
@parameters char * MIME          type of MIME<BR>
           XString * program    buffer which will hold the registered program.
@returns     BOOL result
*/
BOOL XWebView::GetViewer(const char *MIMEType, XString * program)
{
	WXVIEWER view;

	if (WXViewQueryViewer(winhandle, (PSZ) MIMEType, &view, sizeof(view)) == 0)
	{
		*program = view.szProgram;
		return TRUE;
	}
	else
		return FALSE;
}


/*@ XWebView::GetPointer(const LONG pointerType)
@group Pointer
@remarks Get a pointer.
@parameters <t 'ø' c=2>
				øLONG pointerType   øthe pointer to request:
										<t 'ø' c=1>
                                 øWEB_POINTER_NORMAL
                                 øWEB_POINTER_WAIT
                                 øWEB_POINTER_ANCHOR
                                 øWEB_POINTER_UNKNOWN
										</t>
				</t>
@returns     OOL_POINTERHNDLE   handle of the pointer.
*/
OOL_POINTERHANDLE XWebView::GetPointer(const LONG pointerType)
{
	return WXViewQueryPointer(winhandle, pointerType);
}


/*@ XWebView::SetPointer(const OOL_POINTERHANDLE pointer, const LONG pointerType)
@group Pointer
@remarks Get a pointer.
@parameters <t 'ø' c=2>
				øOOL_POINTERHANDLE   øhandle of the pointer to set
           øLONG pointerType   øthe pointer to set:
										<t 'ø' c=1>
                                 øWEB_POINTER_NORMAL
                                 øWEB_POINTER_WAIT
                                 øWEB_POINTER_ANCHOR
                                 øWEB_POINTER_UNKNOWN
										</t>
				</t>
@returns BOOL success
*/
BOOL XWebView::SetPointer(const OOL_POINTERHANDLE pointer, const LONG pointerType)
{
	if (WXViewSetPointer(winhandle, pointerType, pointer) == 0)
		return TRUE;
	else
		return FALSE;
}


/*@ XWebView::SetExtMap(const char *extension, const char *MIMEType, const SHORT format)
@group MIME
@remarks Associate a file-extension with a MIME-type
@parameters  <t 'ø' c=2>
				øchar * extension     øfile-extension
            øchar * MIME          øtype of MIME
            øSHORT format         øformat:
											<t 'ø' c=1>
                                    øWEB_FORMAT_BINARY
                                    øWEB_FORMAT_7BIT
                                    øWEB_FORMAT_8BIT
											</t>
				</t>
@returns     BOOL result
*/
BOOL XWebView::SetExtMap(const char *extension, const char *MIMEType, const SHORT format)
{
	WXEXTMAP map;

	map.wxFormat = format;
	strcpy(map.szExtension, extension);
	strcpy(map.szMIMEType, MIMEType);
	if (WXViewSetExtMap(winhandle, &map, sizeof(map)) == 0)
		return TRUE;
	else
		return FALSE;
}


/*@ XWebView::GetExtMap(const char *extension, XString * MIMEType, SHORT & format)
@group MIME
@remarks Get an association of a file-extension with a MIME-type
@parameters  <t 'ø' c=2>
				øchar * extension     øfile-extension
            øXString * MIME       øbuffer for the type of MIME
            øSHORT& format        øbuffer for format, on result you may receive:
											<t 'ø' c=1>
                                    øWEB_FORMAT_BINARY
                                    øWEB_FORMAT_7BIT
                                    øWEB_FORMAT_8BIT
											</t>
				</t>
@returns     BOOL result
*/
BOOL XWebView::GetExtMap(const char *extension, XString * MIMEType, SHORT & format)
{
	WXEXTMAP map;

	if (WXViewQueryExtMap(winhandle, (PSZ) extension, &map, sizeof(map)) == 0)
	{
		format = map.wxFormat;
		*MIMEType = map.szMIMEType;
		return TRUE;
	}
	else
		return FALSE;
}


/*@ XWebView::StopLoading(void)
@group load data
@remarks Stops loading data.
*/
void XWebView::StopLoading(void) const
{
	WXViewCancelLoad(winhandle);
}


/*@ XWebView::IsLoading(void)
@group load data
@remarks Get if the control is loading data.
@returns     BOOL result
*/
BOOL XWebView::IsLoading(void) const
{
	return WXViewIsLoading(winhandle);
}


/*@ XWebView::GetLastLoadError(void)
@group error handling
@remarks Get for the lasterror which occures when data was loaded.
@returns     LONG result
*/
LONG XWebView::GetLastLoadError(void) const
{
	return WXViewQueryLastLoadError(winhandle);
}


/*@ XWebView::GetLastError(void)
@group error handling
@remarks Get the last error-code.
@returns     LONG result
*/
LONG XWebView::GetLastError(void) const
{
	return WXViewQueryLastError(winhandle);
}


/*@ XWebView::SaveToFile(const char *url, const char *filePath, const BOOL reload)
@group load data
@remarks Load data and save it to a file
@parameters  <t 'ø' c=2>
				øchar * url     øfull qualified URL
            øchar * file    øfull qualified path + filename
            øBOOL reload   øTRUE=do not use cached data<BR> FALSE=use cache
				</t>
@returns     LONG result
*/
LONG XWebView::SaveToFile(const char *url, const char *filePath, const BOOL reload)
{
	return WXViewLoadToFile(winhandle, (PCSZ) url, (PCSZ) filePath, (reload ? WXLOAD_ANCHOR | WXLOAD_FORCERELOAD : WXLOAD_ANCHOR), NULL);
}


BOOL webDefHandler::HandleEvent(ULONG msg, void *mp1, void *mp2)
{
	switch (msg)
	{
		case WX_MSGERROR:
		{
			PWXMSGDATA data = (PWXMSGDATA) mp2;

			web->HandleError(data->ulMsgID, (char *) data->pwxMsgData);
		}
		break;
	case WX_LOADSTATUS:
		{
			PWXTHREADDATA data = (PWXTHREADDATA) mp2;

			if (data[0].wxflState > 0)
				web->LoadProgress(data[0].wxflState);
			else
				web->LoadProgress(data[1].wxflState);
		}
		return TRUE;
	case WX_LOADRESULT:
		web->LoadResult((LONG) SHORT1FROMMP(mp2));
		return TRUE;
	case WX_BUTTONCLICK:
		{
			PWXBUTTONDATA data = (PWXBUTTONDATA) mp2;
			WXPOS pos;

			web->ButtonPressed(data->usButtonNum, data->x, data->y);
			if (WXViewQueryPos(web->GetHandle(), data->x, data->y, &pos) != 0)
				return FALSE;
			if (WXViewQueryAnchorLen(web->GetHandle(), &pos) == 0)
				return TRUE;
			char anchor[1024];

			if (WXViewQueryAnchor(web->GetHandle(), &pos, (PSZ) anchor, 1024) != 0)
				return TRUE;
			web->Load(anchor);
			return TRUE;
		}
		break;
	}
	return FALSE;
}


/*docs only*/

/*@ XWebView::ButtonPressed()
@group misc
@remarks Override this function to get information when a mouse-button was pressed.
@parameters  <t 'ø' c=2>
				øSHORT    øbuttonNumber
            øSHORT    øxPosition in window-coordinates
            øSHORT    øyPosition in window-coordinates
				</t>
*/


/*@ XWebView::HandleError()
@group error handling
@remarks Override this function to get information on runtime-errors
@parameters  ULONG    errorCode
            char *   errorMessage
*/


/*@ XWebView::LoadResult()
@group error handling
@remarks Override this function to get information of the success of loading data.
@parameters  ULONG    result, possible values are:
                        WEB_SUCCESS
                        WEB_ERROR
                        WEB_CANCELLED
*/


/*@ XWebView::LoadProgress()
@group error handling
@remarks Override this function to get information of progress of loading data
@parameters  ULONG    state, possible values are:
                        WEB_CONNECT
                        WEB_WAIT
                        WEB_LOADDATA
                        WEB_RENDER
*/
