/* a basic+ test of the embedded browser CONTROL
Requires IWBASIC 2.0 or greater 
Compile as a WINDOWS target
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
modified to add history window
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
*/

$INCLUDE "string.inc" 
$include "ctl.inc"
$use "wininet.lib"
int gn
window ctwin
int history_visible=0
Const LB_RESETCONTENT  = 0x184

TYPE BROWSERDATA
	WINDOW win
	WINDOW urldlg
	WINDOW cont
	window history
ENDTYPE

'$macro ARRAYCOUNT(x) (sizeof(x)/sizeof(x[0]))
class CRect,WINRECT
	declare width(),int
	declare height(),int
endclass

sub CRect::width(),int
	return right-left+1
endsub

sub CRect::height(),int
	return bottom-top+1
endsub

INT tbArray[11]
INT g_WindowCount
pointer g_list

CONST idBack = 0x100
CONST idForward = 0x101
CONST idStop = 0x102
CONST idRefresh = 0x103
CONST idHome = 0x104
CONST idSearch = 0x105
CONST idPrint = 0x106
CONST idSave = 0x107
CONST idHistory = 0x108
const OLECMDID_SAVEAS = 4
const OLECMDEXECOPT_DODEFAULT = 0
const CW_USEDEFAULT = 0x80000000
const WS_OVERLAPPEDWINDOW = 0x00CF0000

DECLARE IMPORT, GetSysColor(nIndex as INT),UINT
declare import, CreateWindowExA(int q,pointer q,pointer q,int q,int q,int q,int q,int q,int q,int q,int q,int q),int
declare import, DestroyWindow(int q)
declare import, GetWindowRect(int q,pointer q)

'create a toolbar. It will send its messages to the main WINDOW
tbArray = idBack, idForward, idStop, idRefresh, idHome, 0, idSearch, idPrint, idSave,idHistory

'open our main WINDOW and browser containing WINDOW
pointer pFirstWindow = CreateBrowserWindow()
settype pFirstWindow, BROWSERDATA

'Browse to some page
BROWSECMD *pFirstWindow.cont, @NAVIGATE, "http://www.ionicwind.com"

WAITUNTIL g_WindowCount=0
' free the list
if (g_list) then ListRemoveAll(g_list, TRUE)
END



sub CreateBrowserWindow(),pointer
	pointer p = 0

	' find the first unused BROWSERDATA
	if (g_list)
		pointer pos
		for pos = each g_list as BROWSERDATA
			if (!*pos.win.hWnd)
				p = pos
				break
			endif
		next
	endif

	' found a free node?
	if (!p)
		p = new BROWSERDATA
		if (!g_list) then g_list = ListCreate()
		ListAdd(g_list, p)
	endif

	' open a dummy window
	int h = CreateWindowExA(0,"BUTTON","",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,0,0,0,0)
	CRect rc
	GetWindowRect(h, &rc)
	DestroyWindow(h)

	WITH *p ' ".expression" will be converted to "*p.expression"

		'open our main WINDOW and browser containing WINDOW
		OPENWINDOW (.win, rc.left, rc.top, rc.width(), rc.height(), @NOAUTODRAW|@SIZE|@MINBOX|@MAXBOX, 0, "BROWSER TEST", &handler)
		OPENWINDOW (.cont, 0, 0, 600, 680, @NOAUTODRAW|@NOCAPTION, .win, "", &browsehandler)
		OPENWINDOW (.history, 0, 0, 300, 680, 0, .win, "Browsing History", &historyhandler)

		'A URL entry WINDOW used as a toolbar
		OPENWINDOW (.urldlg, 0, 0, 800, 35, @NOAUTODRAW|@NOCAPTION|@BORDER, .win, "", &UrlHandler)
		CONTROL (.urldlg, @EDIT, "", 54, 6, 500, 22, @CTEDITMULTI|@CTEDITRETURN|@CTEDITAUTOV, 2)
		CONTROL (.urldlg, @STATIC, "URL", 21, 8, 31, 16, 0x5000010B, 3)
		SETWINDOWCOLOR (.urldlg, GetSysColor(15))
		SETFONT (.urldlg, "MS Sans Serif", -13, 400, 0, 2)

		'add a status WINDOW for messages
		CONTROL (.win, @STATUS, "Status", 0, 0, 0, 0, 0, 2)

		LOADTOOLBAR(.win, "", 999, tbArray, sizeof(tbArray)/sizeof(tbArray[0]), @TBTOP | @TBLIST)
		CONTROLCMD (.win, 999, @TBSETLABELS, "Back|Forward|Stop|Refresh|Home|Search|Print|Save|History||")
		CONTROLCMD (.win, 999, @TBRESIZE)
		CONTROLCMD (.win, 999, @TBENABLEBUTTON, idBack, FALSE)
		CONTROLCMD (.win, 999, @TBENABLEBUTTON, idForward, FALSE)

		ATTACHBROWSER (.cont)
		'Set the browser, status WINDOW and toolbars initial size
		ResizeAll(.win, .cont, .urldlg, .history)
	ENDWITH
	return p
endsub


SUB browsehandler(),int
	STRING caption
	IDispatch browser
	' @HITWINDOW points to BROWSERDATA.cont
	pointer p = @HITWINDOW - offsetof(BROWSERDATA, cont)
	settype p, BROWSERDATA

	WITH *p
		SELECT @CLASS
		CASE @IDBEFORENAV
			' @LPARAM = IDispatch of the browser's frame
			' filter out only the top frame
			browser = GETBROWSERINTERFACE(.cont)
			if @LPARAM == browser
				BROWSECMD(.cont, @GETNAVURL, caption, 255)
				SETCAPTION (.win, caption)
				SETCONTROLTEXT (.urldlg, 2, caption)
			endif
			browser->Release()

		CASE @IDDOCUMENTCOMPLETE
			'best place to update toolbar buttons
			CONTROLCMD (.win, 999, @TBENABLEBUTTON, idBack, BROWSECMD(.cont, @BACKENABLED))
			CONTROLCMD (.win, 999, @TBENABLEBUTTON, idForward, BROWSECMD(.cont, @FORWARDENABLED))

		CASE @IDSTATUSTEXTUPDATE
			BROWSECMD (.cont,@GETSTATUSTEXT,caption,255)
			CONTROLCMD (.win,2,@SWSETPANETEXT,0,caption)

/*		CASE @IDNEWWINDOW2
			' @LPARAM=&IDispatch
			' to cancel this "popup", execute BROWSECMD .cont, @CANCELNAV
			' to continue in a custom window, use the following:
			p = CreateBrowserWindow()
			browser = GETBROWSERINTERFACE(.cont)
			browser->AddRef()
			*<COMREF>@LPARAM = browser*/

		CASE @IDNEWWINDOW3
			' @WPARAM=@NWMF_** flags
			' @LPARAM=&IDispatch
			' to cancel this "popup", execute BROWSECMD .cont, @CANCELNAV
			' to continue in a custom window, use the following:
			if ((@WPARAM & @NWMF_OVERRIDEKEY) _
			or ((@WPARAM & (@NWMF_FIRST_USERINITED|@NWMF_USERINITED)) == (@NWMF_FIRST_USERINITED|@NWMF_USERINITED)))
				' allow
				p = CreateBrowserWindow()
				browser = GETBROWSERINTERFACE(.cont)
				browser->AddRef()
				*<COMREF>@LPARAM = browser
			else
				' deny
				BROWSECMD (.cont, @CANCELNAV)
				' play a sound: "popup blocked"
			endif

		ENDSELECT
	ENDWITH
	RETURN 0
ENDSUB


SUB handler(),int
	' @HITWINDOW points to BROWSERDATA.win
	pointer p = @HITWINDOW - offsetof(BROWSERDATA,win)
	settype p, BROWSERDATA

	WITH *p
		SELECT @CLASS
		CASE @IDCREATE
			g_WindowCount++

		CASE @IDDESTROY
			g_WindowCount--

		CASE @IDCLOSEWINDOW
			CLOSEWINDOW (.urldlg) ' *p.urldlg)
			CLOSEWINDOW (.cont)
			CLOSEWINDOW (.win)
			CLOSEWINDOW (.history)

		CASE @IDSIZE
			ResizeAll(.win, .cont, .urldlg,.history)

		CASE @IDCONTROL
			IF @NOTIFYCODE = 0 /* ignore any tooltip messages */
				SELECT @CONTROLID
					CASE idBack
						BROWSECMD (.cont,@GOBACK)

					CASE idForward
						BROWSECMD (.cont,@GOFORWARD)

					CASE idStop
						BROWSECMD (.cont,@BROWSESTOP)

					CASE idRefresh
						BROWSECMD (.cont,@REFRESH)

					CASE idHome
						BROWSECMD (.cont,@GOHOME)

					CASE idSearch
						BROWSECMD (.cont,@BROWSESEARCH)

					CASE idPrint
						BROWSECMD (.cont,@BROWSEPRINT)

					CASE idSave
						IDispatch browser = GETBROWSERINTERFACE(.cont)
						browser.ExecWB(OLECMDID_SAVEAS, OLECMDEXECOPT_DODEFAULT)
						browser->Release()

					case idHistory
						LoadHistory(.history)
						history_visible=1
						ResizeAll(.win, .cont, .urldlg,.history)
				ENDSELECT
			ENDIF
		ENDSELECT
	ENDWITH
	RETURN 0
ENDSUB


SUB UrlHandler(),int
	' @HITWINDOW points to BROWSERDATA.urldlg
	pointer p = @HITWINDOW - offsetof(BROWSERDATA,urldlg)
	settype p, BROWSERDATA
	DEF temp as STRING
	DEF rcClient as WINRECT

	SELECT @CLASS
		CASE @IDCONTROL

			SELECT @CONTROLID
				CASE 1
					BROWSECMD *p.cont,@NAVIGATE,GETCONTROLTEXT(*p.urldlg,2)

				CASE 2
					SELECT @NOTIFYCODE
						CASE @ENCHANGE
							temp = GETCONTROLTEXT(*p.urldlg,2)
							IF INSTR(temp,"\n")
								BROWSECMD *p.cont,@NAVIGATE,temp
							ENDIF			
					ENDSELECT
			ENDSELECT

		CASE @IDSIZE
			'dynamically adjust the size of the edit CONTROL.
			GETCLIENTSIZE *p.urldlg,rcClient.left,rcClient.top,rcClient.right,rcClient.bottom
			SETSIZE *p.urldlg,54,6,rcClient.right - 58,22, 2
	ENDSELECT
	RETURN 0
ENDSUB

SUB ResizeAll(WINDOW win, WINDOW cont, WINDOW urldlg,window history)
	'use rects for convenience. 
	'the Get*Size functions return width and height instead of right and bottom
	WINRECT rcClient,rcStatus,rcUrl
	'tell the status bar to resize itself
	CONTROLCMD win,2,@SWRESIZE
	CONTROLCMD win,999,@TBRESIZE
	GETCLIENTSIZE win,rcClient.left,rcClient.top,rcClient.right,rcClient.bottom
	'get the size of the statusbar
	GETSIZE win,rcStatus.left,rcStatus.top,rcStatus.right,rcStatus.bottom,2
	'subtract the 'height' of the status bar CONTROL
	rcClient.bottom -= rcStatus.bottom
	'get the size of the toolbar
	GETSIZE win,rcStatus.left,rcStatus.top,rcStatus.right,rcStatus.bottom,999
	'subtract the 'height' of the toolbar. Do this by increasing the top of the rectangle by
	'the height of the toolbar and also reducing the height of the rectangle accordingly
	rcClient.top += rcStatus.bottom
	rcClient.bottom -= rcStatus.bottom
	'make room for our URL entry WINDOW
	GETSIZE urldlg,rcUrl.left,rcUrl.top,rcUrl.right,rcUrl.bottom
	rcClient.top += rcUrl.bottom
	rcClient.bottom -= rcUrl.bottom
	if history_visible
		'set the size of the browsers containing WINDOW
		SETSIZE cont,rcClient.left+300,rcClient.top,rcClient.right,rcClient.bottom
		'set the size of the history containing WINDOW
		SETSIZE history,rcClient.left,rcClient.top,300/*rcClient.right*/,rcClient.bottom
	else
		'set the size of the browsers containing WINDOW
		SETSIZE cont,rcClient.left,rcClient.top,rcClient.right,rcClient.bottom
		'set the size of the history containing WINDOW
		SETSIZE history,rcClient.left,rcClient.top,0/*rcClient.right*/,0/*rcClient.bottom*/
	endif
	'finally set the size of the url WINDOW
	SETSIZE urldlg,rcClient.left,rcClient.top-rcUrl.bottom,rcClient.right,rcUrl.bottom

ENDSUB

SUB historyHandler(),int
	' @HITWINDOW points to BROWSERDATA.urldlg
	pointer p = @HITWINDOW - offsetof(BROWSERDATA,history)
	settype p, BROWSERDATA
	DEF temp as STRING
	DEF rcClient as WINRECT

	SELECT @CLASS
		case @IDCREATE
			WINRECT hr
			GETCLIENTSIZE (#p.history,hr.left,hr.top,hr.right,hr.bottom)
			CONTROL(#p.history, @listbox, "vv", 0, 0, hr.right,hr.bottom-100,@HSCROLL|@VSCROLL|@CTLISTNOTIFY, 888)
			SETFONT (#p.history, "Tahoma", 10, 400, 0, 888)
conLBRightClick(#p.history,888,&handleright)
ctwin=#p.history
		case @idmenupick
			if @menunum=99
				istring selurl[260]=GETSTRING (#p.history, 888, gn)
				messagebox #p.history,"Execute "+selurl+"\nwhere the messagebox is located","Execute",0
			endif
		CASE @IDCONTROL
			SELECT @CONTROLID
				CASE 888
					if @notifycode=@LBNDBLCLK
						BROWSECMD *p.cont,@NAVIGATE,GETSTRING(#p.history, 888,GETSELECTED (#p.history, 888))
						history_visible=0
						ResizeAll(#p.win, #p.cont, #p.urldlg, #p.history)
					endif
				default
			ENDSELECT
		CASE @IDCLOSEWINDOW
			history_visible=0
			ResizeAll(#p.win, #p.cont, #p.urldlg, #p.history)
		CASE @IDSIZE
			'dynamically adjust the size of the listbox CONTROL.
			GETCLIENTSIZE #p.history,rcClient.left,rcClient.top,rcClient.right,rcClient.bottom
			SETSIZE #p.history,0,0,rcClient.right,rcClient.bottom, 888
	ENDSELECT
	RETURN 0
ENDSUB

sub LoadHistory( window win)
	SendMessage(win,LB_RESETCONTENT,0,0,888)
	SETHORIZEXTENT (win, 888, 600)
	ADDSTRING win, 888, "http://www.ionicwind.com"
	ADDSTRING win, 888, "http://www.ionicwind.com/forums"
	ADDSTRING win, 888, "http://www.codingmonkeys.com"
	ADDSTRING win, 888, "http://www.ionicwind.com/forums/index.php?topic=4754.msg36851#msg36851"
return
endsub

sub handleright(n:int,x:int,y:int)
	gn=n
	CONTEXTMENU ctwin,x,y
		MENUITEM "Open security centre ",0,99
	ENDMENU
endsub