/*
-----------------------------------------------------------------------------
This source file is part of OpenSpace3D
For the latest info, see http://www.openspace3d.com

Copyright (c) 2011 I-maginer

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt
-----------------------------------------------------------------------------
*/

/** \mainpage Embedded Web Navigator Scol Plugin
 *
 * \section intro_sec Introduction
 * This plugin allow Scol Virtual Machine to use Google Chrome interfaces
 */

/** \defgroup grpWebNavigator Web navigator general functions
 *  Creation / deletion functions and generic usage of the web navigator component.
 *  @{
 */
/** @} */

#ifndef _SCOL_EMBEDDED_WEB_NAVIGATOR_PLUGIN_
#define _SCOL_EMBEDDED_WEB_NAVIGATOR_PLUGIN_

#include "embeddedWebNavigatorPrerequisites.h"

extern cbmachine ww;
extern ScolWindowHandle HScol ;		//Scol window Handle

// Object type definition, declared in scolEmbeddedWebNavigator.cpp
extern int OBJWEBNAVIGATORSCOL;

// Web navigator reflexives identifiers
#define WEB_NAVIGATOR_LIFESPAN_ON_POPUP_CB    0
#define WEB_NAVIGATOR_LIFESPAN_RUN_MODAL_CB          1
#define WEB_NAVIGATOR_LOAD_ON_START_CB               2
#define WEB_NAVIGATOR_LOAD_ON_END_CB                 3
#define WEB_NAVIGATOR_LOAD_ON_ERROR_CB               4
#define WEB_NAVIGATOR_DISPLAY_ON_NAV_STATE_CHANGE_CB 5
#define WEB_NAVIGATOR_DISPLAY_ON_ADDRESS_CHANGE_CB   6
#define WEB_NAVIGATOR_DISPLAY_ON_TITLE_CHANGE_CB     7
#define WEB_NAVIGATOR_DISPLAY_ON_TOOLTIP_CB          8
#define WEB_NAVIGATOR_DISPLAY_ON_STATUS_MESSAGE_CB   9
#define WEB_NAVIGATOR_DISPLAY_ON_CONSOLE_MESSAGE_CB  10
#define WEB_NAVIGATOR_FIND_ON_RESULT_CB              11
#define WEB_NAVIGATOR_JS_ON_EXTERNAL_CALL_CB         12
#define WEB_NAVIGATOR_JS_ON_EXTERNAL_CALL_STR_CB     13
#define WEB_NAVIGATOR_MAX_CB                         14

// Useful defines
#define	ASSERT assert
#define DELETEARRAY(x)		if (x) { delete []x;		x = NULL; }
#define CHECKALLOC(x)		if(!x) { return false;}

// Useful macro to generate a reflexive function addition
#ifdef SCOL_DEBUG
  #define WEB_NAVIGATOR_GENERATE_SCOL_ADD_CB_FUNCTION(CB_NAME, CB_ID) \
  int WebNavigatorCb##CB_NAME##(mmachine m) \
  {\
    MMechostr(MSKDEBUG, "WebNavigatorCb##CB_NAME##\n");\
    return OBJaddreflex (m, OBJWEBNAVIGATORSCOL, CB_ID);\
  }
#else
  #define WEB_NAVIGATOR_GENERATE_SCOL_ADD_CB_FUNCTION(CB_NAME, CB_ID) \
  int WebNavigatorCb##CB_NAME##(mmachine m) \
  {\
    return OBJaddreflex (m, OBJWEBNAVIGATORSCOL, CB_ID);\
  }
#endif

/** \ingroup grpWebNavigator
 * \brief WebNavigatorCreate : This function create a new Embedded Web Navigator Object
 *
 * <b>Prototype:</b> fun [Chn ObjWin I I I I S] ObjWebNavigator
 * \param Chn : the current channel
 * \param ObjWin : the parent window on which the web navigator will be created
 * \param I : Horizontal position from the left border of the parent window, in pixels
 * \param I : Vertical position from the top border of the parent window, in pixels
 * \param I : Width of the web navigator
 * \param I : Height of the web navigator
 * \param S : Optional start url.
 *
 * \return ObjWebNavigator : The new Embedded Web Navigator Object
 */
int WebNavigatorCreate(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorCreate : This function create a new Embedded Web Navigator Object which render it's content "offscreen"
 *
 * <b>Prototype:</b> fun [Chn ObjWin I I S] ObjWebNavigator
 * \param Chn : the current channel
 * \param ObjWin : the parent window on which the web navigator will be created. Optional (could be nil), but needed for mouse cursor update and popup windows docking.
 * \param I : Width of the web navigator
 * \param I : Height of the web navigator
 * \param I : Transparency 0 or 1 to enable
 * \param S : Optional start url.
 *
 * \return ObjWebNavigator : The new Embedded Web Navigator Object
 */
int WebNavigatorCreateOffscreen(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorDestroy : This function destroy a Embedded Web Navigator Object
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the current Embedded web navigator object
 *
 * \return I : 0 if success
 */
int WebNavigatorDestroy(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorLoadURL : Load the given url
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The URL to load
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorLoadURL(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorLoadFile : Load the given file
 *
 * <b>Prototype:</b> fun [ObjWebNavigator P S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The path of the file to load
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorLoadFile(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorLoadHTML : Load the given html text
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The HTML content to load
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorLoadHTML(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorActionUndo : Execute undo on a frame.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorActionUndo(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorActionRedo : Execute redo on a frame.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorActionRedo(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorActionCut : Execute cut on a frame.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorActionCut(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorActionCopy : Execute copy on a frame.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorActionCopy(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorActionPaste : Execute paste on a frame.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorActionPaste(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorActionDelete : Execute delete on a frame.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorActionDelete(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorActionSelectAll : Execute select all on a frame.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorActionSelectAll(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorPrint : Execute printing on a frame. The user will be prompted with the print dialog appropriate to the operating system.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorPrint(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorViewSource : Save a frame's HTML source to a temporary file and open it in the default text viewing application.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorViewSource(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorGetSource : Returns a frame's HTML source as a string.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] S
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return S : the html source as string, NIL otherwise
 */
int WebNavigatorGetSource(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorGetText : Returns a frame's display text as a string.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] S
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return S : the frame text content as string, NIL otherwise
 */
int WebNavigatorGetText(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorExecuteJavaScript : Execute a string of JavaScript code in this frame.
 * The |script_url| parameter is the URL where the script in question can be found, if any.
 * The renderer may request this URL to show the developer the source of the error.
 * The |start_line| parameter is the base line number to use for error reporting.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S S I S] I
 * \param ObjWebNavigator : the web navigator object
 * \param S : The javascript code to execute
 * \param S : the url where the script can be found. target frame url if NIL.
 * \param I : line number for error reporting. 0 if NIL.
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorExecuteJavaScript(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorGetURL : Returns the URL currently loaded in a frame.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator S] S
 * \param ObjWebNavigator : the web navigator object
 * \param S : The target frame name. If NIL, the target is the web navigator main frame.
 *
 * \return S : the frame text content as string, NIL otherwise
 */
int WebNavigatorGetURL(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorCanGoBack : Does the browser can navigate backward?
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if the go back action can be performed on the web navigator, false otherwise. NIL if an error occurs.
 */
int WebNavigatorCanGoBack(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorGoBack : Navigate backward
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorGoBack(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorCanGoForward : Does the browser can navigate forward?
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if the go forward action can be performed on the web navigator, false otherwise. NIL if an error occurs.
 */
int WebNavigatorCanGoForward(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorGoForward : Navigate forward
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorGoForward(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorReload : Reload the current page.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorReload(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorReloadIgnoreCache : Reload the current page ignoring any cached data.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorReloadIgnoreCache(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorStopLoad : Stop loading the page.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorStopLoad(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorFind : Search for text in the current page.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I S I I I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I The search identifier, to allow multiple search simultaneously
 * \param S The searched text
 * \param I 1 to search forward or 0 to search backward, within the page.
 * \param I 1 to indicate that the search should be case-sensitive.
 * \param I 1 to indicate that this is the first request or 0 to indicate that it's a follow-up.
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorFind(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorStopFinding : Cancel all searches that are currently going on.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : 1 to clear the selection, 0 to keep it.
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorStopFinding(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorGetZoomLevel : Get the zoom level.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] F
 * \param ObjWebNavigator : the web navigator object
 *
 * \return F : The actual zoom level, NIL if an error occurs.
 */
int WebNavigatorGetZoomLevel(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorSetZoomLevel : Change the zoom level.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator F] I
 * \param ObjWebNavigator : the web navigator object
 * \param F : the new zoom level
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorSetZoomLevel(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorClearHistory : Clear the back/forward browsing history.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorClearHistory(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorShowDevTools : Open developer tools window.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorShowDevTools(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorCloseDevTools : Close the developer tools window if one exists for this browser instance.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] I
 * \param ObjWebNavigator : the web navigator object
 *
 * \return I : 1 if success, NIL if an error occurs.
 */
int WebNavigatorCloseDevTools(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorGetSize : Retrieve the size of a web navigator object
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] [I I]
 * \param ObjWebNavigator : the web navigator object
 *
 * \return [I I] : size tuple
 * - I : width of the control
 * - I : height of the control
 */
int WebNavigatorGetSize(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorSetSize : Set the size of a web navigator object
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : width of the control, in pixels
 * \param I : height of the control, in pixels
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorSetSize(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorGetPosition : Retrieve the position of a web navigator object
 *
 * <b>Prototype:</b> fun [ObjWebNavigator] [I I]
 * \param ObjWebNavigator : the web navigator object
 *
 * \return [I I] : position tuple
 * - I : position from left border of the parent window, in pixels
 * - I : position from top border of the parent window, in pixels
 */
int WebNavigatorGetPosition(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorSetPosition : Set the position of a web navigator object in his parent window
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : position from left border of the parent window, in pixels
 * \param I : position from top border of the parent window, in pixels
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorSetPosition(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorBlitOffscreen : Copy the content of an offscreen web navigator to the destination bitmap.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator ObjBitmap] ObjBitmap
 * \param ObjWebNavigator : the web navigator object
 * \param ObjBitmap : target bitmap
 *
 * \return ObjBitmap : returns the same bitmap if success, NIL otherwise
 */
int WebNavigatorBlitOffscreen(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorBlitOffscreenAlpha : Copy the content of an offscreen web navigator to the destination alpha bitmap.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator AlphaBitmap] AlphaBitmap
 * \param ObjWebNavigator : the web navigator object
 * \param AlphaBitmap : target alpha bitmap
 *
 * \return AlphaBitmap : returns the same alpha bitmap if success, NIL otherwise
 */
int WebNavigatorBlitOffscreenAlpha(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorInjectKeyDown : Send "key down" event to the web navigator. 
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I I I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : Virtual code of the key to inject
 * \param I : ASCII code
 * \param I : Key modifiers flag (MAJ/CTRL/ALT...)
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorInjectKeyDown(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorInjectKeyUp : Send "key up" event to the web navigator.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : Virtual code of the key to inject
 * \param I : Key modifiers flag (MAJ/CTRL/ALT...)
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorInjectKeyUp(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorInjectKeyMessage : Send "key message" event to the web navigator.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I I I] I
 * \param ObjWebNavigator : the web navigator object
  * \param I : window message
  * \param I : lparam
  * \param I : wparam
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorInjectKeyMessage(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorInjectMouseClick : Send "mouse click" event to the web navigator.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I I I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : Mouse x position
 * \param I : Mouse y position
 * \param I : Mouse button
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorInjectMouseClick(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorInjectMouseMove : Send "mouse move" event to the web navigator.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : Mouse x position
 * \param I : Mouse y position
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorInjectMouseMove(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorInjectMouseWheel : Send "mouse wheel" event to the web navigator.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I I I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : Mouse x position
 * \param I : Mouse y position
 * \param I : Mouse wheel delta
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorInjectMouseWheel(mmachine m);

/** \ingroup grpWebNavigator
 * \brief WebNavigatorSetFocus : Send "focus" event to the web navigator.
 *
 * <b>Prototype:</b> fun [ObjWebNavigator I] I
 * \param ObjWebNavigator : the web navigator object
 * \param I : 1 to set focus, 0 to set unfocused
 *
 * \return I : 1 if success, NIL otherwise
 */
int WebNavigatorSetFocus(mmachine m);

#endif
