/* $Header$ */

// OMNIS JavaScript Client
// Common JavaScript Component support classes etc
// Copyright (C) Omnis Software Ltd 2017 onwards

/*************** changes *******************
Date			Edit				Bug					Description
17-Apr-25	bjw0803			ST/JS/3778	Added pEvAfterFired parameter to evBorderIconClicked.
15-Apr-25	jmg1510			ST/JS/3775	Added "one-time-code" suggestion to $autocomplete property.
04-Apr-25	bjw0793			ST/JS/3766	Added field border icon support to the JS client.
20-Feb-25	fhh0098			ST/JS/3714	Add optional indication that an element is scrollable by adding shadow to relevant edges.
11-Oct-24	bjw0771			ST/JS/3469	Added $rightclicksetsline property to list based controls.
24-Jul-23	bjw0686			ST/JS/3327	Added ability to reorder JS Native List at runtime.
30-Sep-22	bjw0590									Changed $vertalign to use kJstVert... core constants.
16-Aug-22	bjw0569			ST/JS/3013	Added layout properties to JS push, trans & split button.
04-May-22	dmw0526			ST/JS/2946		Add base JS property $entertodoubleclick.
28-Apr-22	dmw0522			ST/JS/2974		Add $datepickeroptions to customize options in a popup date picker.
05-Jan-22	bjw0465                 Added autoPropFont auto property type.
07-Dec-21	dmw0466			ST/JS/2405		Added mComponentVersion to external components.
27-Aug-21	bjw0437			ST/JS/2739	Added $defaultinactiveappearance property.
02-Aug-21	bjw0431                 RGBA color property support for JS client.
20-Jan-21		dmw0407									Implemented $vertpadding as a base jsclient property.
13-Jan-20		dmw0398									Implemented $horzpadding as a base jsclient property.
27-Oct-20	bjw0375			ST/JS/2450	Nav menu properties were not set correctly after conversion before re-saving the form.
26-Oct-20	rmm10726		ST/CO/306		Conversion to 10.2 added an item to empty component item lists.
01-Sep-20	jmg1035c								Support $hasshadow in external jscomps. (Added jsInsertDefaultAttributes())
24-Aug-20	jmg_themes							Simplified with use of GDIgetJavaScriptColor().
17-Jul-20	dmw0322									Initial theme implementation.
29-Jun-20	rmm_od									Use obrowser for design mode rendering of remote forms.
08-Jun-20	rmm_svg2								SVG support for JS client.
14-Oct-19	rmm10286								Fixed crashes in jssuper.
09-Oct-19	jmgxcomp								Simplified process of creating xcomps. (Unmarked - too many changes)
13-Feb-18	dmw0200			ST/JS/1977	Fixed issue with random values being populated for some properties on conversion to Studio 10.
29-Jul-19	jmg0909			ST/JS/2070	Added jsInsertNum overload for qreal value & added get/setQNumProp methods.
09-Jul-19	dmw0233			ST/JS/2064	Added jsInsertVariableNamePropertyWithAttName().
07-Feb-19	dmw0195			ST/NO/076		Added $defaultdisabledappearance property.
04-Dec-18	dmw0179			ST/JS/1901	Added $keyboardchangescurrentline for list controls.
27-Sep-18	bjw0097									Added Accessibility tab to property manager.
01-Aug-18	bjw0059									Accessibility - Added $arialabel, $arialabelledby & $ariadescribedby properties.
10-Jul-18	bjw0048									Error when setQShortProp() was called without optional arguments (overloaded functions had matching signatures).
26-Jun-18	dmw0040									Allow zero to be used in jsInsertNum() and overloaded setQShortProp() to set limit.
02-Jun-17	rmm9400									New JS component to allow controls to be added using just a JSON definition, PNG images and JavaScript implementation.
04-Aug-17 jmg0626a								Removed 'unset' state handling from get/setQBoolProp() methods.
04-Aug-17 jmg0626									Added getQBoolProp() & setQBoolProp() generic methods to javaScriptComponent class.
25-Oct-16	rmm9123									Implemented $exportjson() and $importjson().
18-Oct-16	jmg0494									Added overloaded setQLongProp to allow max & min values to be provided.
17-Oct-16	jmgunmarked							Removed 'on' value from $autocomplete values list (Not valid for us as we don't 'submit' forms).
14-Oct-16	jmg0487			ST/JS/1283	Moved parts of the implementation of $autocorrect, $autocapitalize & $autocomplete into jsSuper
29-Dec-15	rmm8700			ST/JS/464		JS client drag and drop.
02-Jul-15	jmg0277									Reworked  $pagesize property (most logic is now in the core)
16-Jun-15	jmg0260									Added general support for $pagesize property (for list pager)
13-May-15	jmg0256									Tightened some method definitions, to fix warnings (made some char* params const, to allow literal strings).
04-Nov-14	rmm8451									Navigation menu control - JavaScript implementation.
03-Oct-14	rmm8441									Navigation menu control.
21-May-14	jmg0111									Added Generic getter/setter helper functions.
04-Mar-14	jmg0068									Added jsInsertColorPairAttribute() helper function.
03-Jan-14	rmm8205			ST/JS/370		$textishtml
14-Oct-13	rmm8135			OE-2256			Added $datanames group for Omnis X.
25-Jul-13	rmm8068			OE-2211			Property change issues.
06-Jun-13	rmm7999			ST/JS/558		Implemented trans button control for JS client
04-Dec-12	rmm64bit5								Changes required for compiling with 64 bit target.
03-Oct-11	rmm7262			ST/BE/644		Design mode redraw issue.
24-Aug-11	rmm7216									Escape HTML syntax characters when inserting data into HTML output.
09-Aug-11	rmm7215			ST/BE/582		JavaScript client file upload and download support.
12-Jul-11	CRJSCal									Date picker calendar view.
08-Jul-11 mpmPopMenu2							Implements popup menus
09-Jun-11	rmm7146									Issues with button control - need to use a color for Android + other improvements.
14-Apr-11	rmm7101									JS tab strip component.
01-Mar-11	rmm7095									JavaScript client data grid component.
17-Feb-11	CR0010									Checkbox layout and icon changes.
14-Feb-11	CR0009									JS checkbox component.
02-Feb-11	rmm7082									JavaScript client - more HTML generation issues.
01-Feb-11	rmm7081									JavaScript client - HTML generation for subform.
26-Jan-11	rmm7079									JS progress component.
26-Jan-11	rmm7078									No longer use external CSS file for borders ($effect).
25-Jan-11	rmm7077									JS client - objlink change and line picker.
24-Jan-11	rmm7076									JavaScript HTML control server component.
21-Jan-11	rmm7075									Changed JavaScript client id generation.
18-Jan-11	rmm7072									JavaScript label server component.
10-Jan-11	rmm7058									More JavaScript components for design mode.
07-Jan-11	rmm7056									JavaScript client font issues.
15-Sep-10	rmm_jsc									JavaScript client components.
*************************************/

#ifndef _JSSUPER_H_
#define _JSSUPER_H_

#include "extcomp.he"
#include "gdi.he"
#include "hwnd.he"
#include "OmnisComponent.h"
#include "omnisCompFmtNotation.h"
#include "dmconst.he" // bjw0590

const qshort kColorDefault = -1; // dmw0322
// Start jmg0487: Resource IDs & property definitions for editable text components' $auto... properties. Components which use these must include jsEditableTextBase.rc in their .rc file.
const attnumber cAutoCorrect = 4200,
cAutoCapitalize = 4201,
cAutoComplete = 4202,
// dmw0398: Resource IDs 4230-4299 reserved for base properties
cBaseHorzPaddingID = 4230, // used for propID and resource ID for the majority of controls. Call into getHorzPaddingPropID(), as this is overridden in controls that already implemented $horzpadding to maintain their propID.
cBaseVertPaddingID = 4231, // dmw0407: used for propID and resource ID for the majority of controls. Call into getVertPaddingPropID(), as this is overidden in controls that already implemented $vertpadding to maintain their propID.
cBaseDatePickerOptions = 4232, // dmw0522
cEnterToDoubleClick = 4233, // dmw0526
cVertAlign = 4234, // bjw0569
cSplitIconAndText = 4235, // bjw0569
cIconTextSpacing = 4236, // bjw0569

// dmw0179: Resource IDs & property definitions for list components' properties. Components which use these must include jsListBase.rc in their .rc file.
cKeyboardChangesCurrentLine = 4300, // dmw0179
cReorderMode = 4301, // bjw0686
cRightClickSetsLine = 4302; // bjw0771

const qshort cBaseDefaultHorzPadding = 0; // dmw0398
const qshort cBaseDefaultVertPadding = 0; // dmw0407

// Start dmw0522: Popup date picker options flags
const qshort cFlagDatePickerShowHeading = 1,
cFlagDatePickerShowNav = 2,
cFlagDatePickerShowWeekNumbers = 4;
// End dmw0522

const qshort cDefaultDatePickerOptionsFlags = cFlagDatePickerShowHeading | cFlagDatePickerShowNav;

const ECOproperty cPropAutoCorrect = { cAutoCorrect, cAutoCorrect, fftBoolean, EXTD_FLAG_PROPGENERAL,	0,	0,	0 }; // jmg0487
const ECOproperty cPropAutoCapitalize = { cAutoCapitalize,	cAutoCapitalize,	fftInteger,	EXTD_FLAG_PROPGENERAL | EXTD_FLAG_EXTCONSTANT, 0, 6020, 6022 };
const ECOproperty cPropAutoComplete = { cAutoComplete,	cAutoComplete, fftCharacter,	EXTD_FLAG_PROPGENERAL | EXTD_FLAG_ENUM,	EXTD_EFLAG_ENUM_CHAR, 0, 0 }; // rmm9123
// End jmg0487
// Start bjw0059
const ECOproperty cPropAriaLabel = { anumAriaLabel, 0, fftCharacter, EXTD_FLAG_PROPACCESS,	0, 0, 0 }; // bjw0097
const ECOproperty cPropAriaLabelledby = { anumAriaLabelledby, 0, fftCharacter, EXTD_FLAG_PROPACCESS,	0, 0, 0 }; // bjw0097
const ECOproperty cPropAriaDescribedby = { anumAriaDescribedby, 0, fftCharacter, EXTD_FLAG_PROPACCESS,	0, 0, 0 }; // bjw0097
// End bjw0059
const ECOproperty cPropScrollShadowWidth = {anumScrollShadowWidth, 0, fftInteger, EXTD_FLAG_PROPAPP, 0, 0, 0 }; // fhh0098
const ECOproperty cPropScrollShadowColor = {anumScrollShadowColor, 0, fftInteger, EXTD_FLAG_PROPAPP|EXTD_FLAG_PWINDCOL, 0, 0, 0 }; // fhh0098
const ECOproperty cPropKeyboardChangesCurrentLine = { cKeyboardChangesCurrentLine, cKeyboardChangesCurrentLine, fftBoolean, EXTD_FLAG_PROPACT, 0, 0, 0}; // dmw0179
const ECOproperty cPropDefaultDisabledAppearance = { anumDefaultDisabledAppearance, 0, fftBoolean, 0, 0, 0, 0 }; // dmw0195
const ECOproperty cPropDefaultInactiveAppearance = { anumDefaultInactiveAppearance, 0, fftBoolean, 0, 0, 0, 0 }; // bjw0437
const ECOproperty cPropHorzPadding = { cBaseHorzPaddingID, cBaseHorzPaddingID, fftInteger, EXTD_FLAG_PROPAPP, EXTD_EFLAG_AUTOPROP, 0, 0 }; // dmw0398
const ECOproperty cPropVertPadding = { cBaseVertPaddingID, cBaseVertPaddingID, fftInteger, EXTD_FLAG_PROPAPP, EXTD_EFLAG_AUTOPROP, 0, 0 }; // dmw0398
const ECOproperty cPropComponentVersion = { anumVersion, 0, fftInteger, EXTD_FLAG_HIDDEN, 0, 0, 0 };
const ECOproperty cPropDatePickerOptions = { cBaseDatePickerOptions, cBaseDatePickerOptions, fftInteger, EXTD_FLAG_PROPAPP|EXTD_FLAG_PWINDSET|EXTD_FLAG_EXTCONSTANT, EXTD_EFLAG_AUTOPROP, 6500, 6503 }; // dmw0522
const ECOproperty cPropEnterToDoubleClick = { cEnterToDoubleClick, cEnterToDoubleClick, fftBoolean, EXTD_FLAG_PROPACT, EXTD_EFLAG_AUTOPROP, 0, 0 }; // dmw0526
const ECOproperty cPropVertAlign = { cVertAlign, cVertAlign, fftInteger, EXTD_FLAG_PROPTEXT | EXTD_FLAG_INTCONSTANT, EXTD_EFLAG_AUTOPROP, preJstVertF, preJstVertL }; // bjw0569 // bjw0590
const ECOproperty cPropSplitIconAndText = { cSplitIconAndText, cSplitIconAndText, fftBoolean, EXTD_FLAG_PROPAPP, EXTD_EFLAG_AUTOPROP, 0, 0 }; // bjw0569
const ECOproperty cPropIconTextSpacing = { cIconTextSpacing, cIconTextSpacing, fftInteger, EXTD_FLAG_PROPAPP, EXTD_EFLAG_AUTOPROP, 0, 0 }; // bjw0569
const ECOproperty cPropReorderMode = { cReorderMode, cReorderMode, fftInteger, EXTD_FLAG_PROPACT|EXTD_FLAG_EXTCONSTANT, EXTD_EFLAG_AUTOPROP, 6700, 6702 }; // bjw0686
const ECOproperty cPropRightClickSetsLine = { cRightClickSetsLine, cRightClickSetsLine, fftBoolean, EXTD_FLAG_PROPACT, EXTD_EFLAG_AUTOPROP, 0, 0 }; // bjw0771

// bjw0793
const ECOparam jsBorderIconClickedEventParams[] =
{
	6600,	fftBoolean, 0, 0, // pLeftBorderIcon
	6601, fftBoolean, 0, 0, // bjw0803: pEvAfterFired
};

const ECOmethodEvent cEventBorderIconClicked = { ECE_BORDERICONCLICKED, 0, 0, 2, (ECOparam*)&jsBorderIconClickedEventParams[0], 0, 0 }; // bjw0793 // bjw0803

/// Populates an enum property list with values for $autocomplete.
/// Call from component's WndProc's ECM_GETPROPERTYENUMS message.
inline void setAutoCompleteValuesEnum(EXTCompInfo* eci) // jmg0487
{
	// rmm9123: Memory leak fixed
	EXTqlist autoCompleteValues(listVlen);
	autoCompleteValues.addCol(fftCharacter, dpFcharacter);

	str80 values[] = { // Array of values to populate the list with
		str80(QTEXT("off")),
		str80(QTEXT("email")),
		str80(QTEXT("name")),
		str80(QTEXT("given-name")),
		str80(QTEXT("family-name")),
		str80(QTEXT("tel")),
		str80(QTEXT("street-address")),
		str80(QTEXT("postal-code")),
		str80(QTEXT("username")),
		str80(QTEXT("current-password")),
		str80(QTEXT("one-time-code")) // jmg1510
	};
	short valuesCount = sizeof(values) / sizeof(str80);

	EXTfldval fval;

	for (short i = 0; i < valuesCount; i++)
	{
		qlong line = autoCompleteValues.insertRow();
		autoCompleteValues.getColValRef(line, 1, fval, qtrue);
		fval.setChar(values[i]);
	}

	EXTfldval	extfldval;
	extfldval.setList(&autoCompleteValues, qtrue);
	ECOaddParam(eci, &extfldval);
}

struct JSCcontrol;
class javaScriptComponent;
struct OMNISControlDefinition;
struct OmnisJSControlDefinition;
struct JSChtmlOptions;
struct WCCcontrol;
struct InnerHtmlDef;
							

// Class to handle format notation when it needs to be specially processed by the control.  This typically
// occurs when the control manages a list of properties e.g. the list of segments for the segmented control.
// As well as being used for format notation, setListLineCount is also used to change the number of lines in the list at runtime.
class webClientComponent_formatNotation: public omnisComponent_formatNotation
{
public:
	webClientComponent_formatNotation() {}
	virtual ~webClientComponent_formatNotation() {}
	
	static void clearBooleanProperty(qlong pPropId);	// rmm8068
};
typedef webClientComponent_formatNotation* (*FMTclassMakeFunc_Legacy)(WCCcontrol*); // rmm9400: Pass WCCcontrol *

typedef qbool(*JSC_GETINNERHTML_LEGACY)(HWND pHwnd, WCCcontrol* pControl, javaScriptComponent* pObject, EXTfldval& pInnerHtml, qdim pWidth, qdim pHeight);			// Function to get inner HTML for JavaScript client
typedef qbool(*JSC_GETINNERHTML)(HWND pHwnd, JSCcontrol* pControl, javaScriptComponent* pObject, EXTfldval& pInnerHtml, qdim pWidth, qdim pHeight);			// Function to get inner HTML for JavaScript client

typedef void (*JSC_APPENDCONTROLSTYLES_LEGACY)(HWND pHwnd, WCCcontrol* pControl, EXTfldval& pStyles, javaScriptComponent* pObject);	// Function to append control-specific styles for JavaScript client // rmm7146

// Definition of an Omnis Web Client control
struct WCCcontrol
{
	JSCcontrol* mCachedJSControl;			// A static cache of this WCCcontrol converted to OMNISControlDefinition & OmnisJSControlDefinition structs.
	qlong								mLibResName;					// Resource number of library
	qlong								mObjectID;						// External component object id
	qlong								mIconID;							// ICON id for control
	qlong								mEventCount;					// Count of events
	ECOmethodEvent* mEvents;							// Control events
	qlong								mPropertyCount;				// Count of properties
	ECOproperty* mProperties;					// Control properties
	qlong								mFirstConstant;				// First constant resource; zero if no constants
	qlong								mLastConstant;				// Last constant resource; zero if no constants
	qlong								mCompFlags;						// Flags sent in response to ECM_IPHONE_OR_JAVASCRIPT_COMPFLAGS
	qlong								mWccFlags;						// WCC_FLAG_... flags
#ifndef isiphone
	qlong							mCompStoreGroupRes;		// Resource number of component store group
#endif
	qlong								mMethodCount;					// Count of methods
	ECOmethodEvent* mMethods;						// Control methods
	FMTclassMakeFunc_Legacy mMakeFmtClass;				// Function to make class notation object
#ifndef isiphone
	qlong							mCustomTabName;				// Resource number of custom tab
	qdim							mFixedLandscapeWidth;	// Fixed landscape width for control (zero if any width allowed) (if landscape is non-zero, portrait must also be non-zero, and vice-versa)
	qdim							mFixedLandscapeHeight;// Fixed landscape height for control (zero if any height allowed) (if landscape is non-zero, portrait must also be non-zero, and vice-versa)
	qdim							mFixedPortraitWidth;	// Fixed portrait width for control (zero if any width allowed) (if landscape is non-zero, portrait must also be non-zero, and vice-versa)
	qdim							mFixedPortraitHeight;	// Fixed portrait height for control (zero if any height allowed) (if landscape is non-zero, portrait must also be non-zero, and vice-versa)
	JSChtmlOptions* mHtmlOptions;				// rmm7082: JavaScript client HTML options
	JSC_GETINNERHTML_LEGACY	mGetInnerHtml;				// rmm7082: JavaScript client function to get inner HTML
	JSC_APPENDCONTROLSTYLES_LEGACY mAppendControlStyles;	// rmm7082: JavaScript client function to append control-specific styles
	const char* mJscCtrlName;					// rmm7082: JavaScript client control name
	attnumber					mControlNameAnum;			// Attribute for control name when mJscCtrlName is to be overridden
#endif
};

class javaScriptComponent : public OmnisComponent
{
public:
#ifndef isiphone
	qdim						mHorzScrollAmt;	// rmm7095: for fields that require their own scroll support
	qdim						mVertScrollAmt;	// rmm7095
	qdim						pageUnits(HWND pHwnd, qbool pVert);	// rmm7095
#else
	qbool						mEnabled;				// Last state set by WM_FLD_ENABLE/DISABLE
#endif
	qbool						mUseDefaultEraseBackground;	// rmm8441
	qbool						mBackgroundUsesPattern;			// rmm8441
	qbool						mUseObrowser;								// rmm_od: True when using obrowser to render remote form design mode

	// [[deprecated]]
	WCCcontrol* mControl; // Legacy. Pointer to WCCcontrol structure (if it is an old-style JS component which uses one)
	JSCcontrol* mJSCcontrol; // Contains the control type's definition, split into mOmnisControlDef & mJSControlDef. 
	
	friend class ComponentDelegate;



private:

	void insertPropertyIntoInnerHtml(EXTfldval& pInnerHtml, InnerHtmlDef innerHtmlDef);

	static JSCcontrol* convertWCCcontrolToJSControl(WCCcontrol* pControl);
	static void jsInsertStyle(HWND pHwnd, JSChtmlOptions* pHtmlOptions, EXTfldval& pInnerHtml, qdim pWidth, qdim pHeight, javaScriptComponent* pObject = 0, WCCcontrol *pLegacyControl = 0); // rmm10286
	static qbool getInnerHtml(EXTCompInfo* pEci, HWND pHwnd, JSCcontrol* pControl, javaScriptComponent* pObject, EXTfldval& pInnerHtml, qdim pWidth, qdim pHeight);
	
	// Start dmw0322
	// Inserts a JSON member name into the given EXTfldval enclosed in ""
	static inline void jsInsertJSONMemberName(EXTfldval& pTheme, str80 pName) 
	{
		pTheme.concat(str15("\""));
		pTheme.concat(pName);
		pTheme.concat(str15("\":"));
	}
	
	// Inserts a JSON member and value for a color.
	// kColorDefault/JSTheme constants are inserted as constants, all others are resolved as a color to send to the client.
	static inline void jsInsertJSONColor(HWND pHwnd, EXTfldval& pTheme, attnumber pAnum, str80 pName, qbool includeComma = qtrue)
	{
		jsInsertJSONMemberName(pTheme, pName);
		
		EXTfldval color;
		str80 colorText;

		ECOgetProperty(pHwnd, pAnum, color);
		qcol colorLong = GDIgetJavaScriptColor(color.getLong()); // jmg_themes
		qlongToString((qlong)colorLong, colorText);

		pTheme.concat(colorText);

		if (includeComma)
			pTheme.concat(str15(","));
	}

	// Inserts a JSON member and value for an integer.
	static inline void jsInsertJSONInteger(HWND pHwnd, EXTfldval& pTheme, attnumber pAnum, str80 pName, qbool includeComma = qtrue)
	{
		jsInsertJSONMemberName(pTheme, pName);
		EXTfldval value;
		str80 valueText;
		ECOgetProperty(pHwnd, pAnum, value);
		qlongToString(value.getLong(), valueText);
		pTheme.concat(valueText);
		if (includeComma)
			pTheme.concat(str15(","));
	}

	// Inserts a JSON member and null value.
	static inline void jsInsertJSONNull(EXTfldval& pTheme, str80 pName, qbool includeComma = qtrue)
	{
		jsInsertJSONMemberName(pTheme, pName);
		pTheme.concat(str15("null"));
		if (includeComma)
			pTheme.concat(str15(","));
	}

	// End dmw0322

	friend LRESULT JSCdefWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci, WCCcontrol* pControl);
	friend LRESULT JSCdefWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci, JSCcontrol* pControl);


public:
	// [[deprecated]]
	javaScriptComponent(HWND pFieldHWnd, WCCcontrol* pControl);
	javaScriptComponent(HWND pFieldHWnd, JSCcontrol* pControl, ComponentDelegate* pCompDelegate = 0);
	virtual ~javaScriptComponent();	
	virtual qbool getCtrlName(EXTfldval& fval) { GDIignore(&fval); return qfalse; }	// Only overridden by the odd control e.g. jsHtml
	virtual void initEmptyControl() {} // bjw0375: Only overridden by the nav menu. Called when generating HTML when there is no open design window.

	// pk_jsc_1
	static void jsGetOuterHTML(EXTCompInfo* eci, HWND pHwnd, JSCcontrol* pControl, EXTfldval& outer, qdim& pWidth, qdim& pHeight);
	static void jsGetControlName(EXTCompInfo* eci, HWND pHwnd, JSCcontrol* pControl, str255& pControlName);

	static void jsGetIconPath(HWND pHwnd, EXTfldval &pIconID, str255& str, qbool includeQuotes = qtrue); // rmm_svg2 // bjw0793
	static void jsAddIconUrl(HWND pHwnd, EXTfldval& pIconID, EXTfldval& pFval, qbool pInsert = qtrue); // rmm_svg2

	static void jsInsert(EXTfldval& insertStr, EXTfldval& dst, qbool pEscapeHTMLsyntaxChars = qtrue); // rmm7216
	static void jsInsertWithAttName(EXTfldval& insertStr, EXTfldval& dst, strxxx &pAttName, qbool pEscapeHTMLsyntaxChars = qtrue);	// rmm7072 // rmm8205
	static void jsInsertIfNotEmpty(const char *pAttName, EXTfldval& insertStr, EXTfldval& dst);	// rmm7215
	static void jsInsert(strxxx& insertStr, EXTfldval& dst, qbool pEscapeHTMLsyntaxChars = qtrue); // rmm7216
	static void jsCheckVariableName(strxxx &pVariableName);	// rmm8135
	static void jsInsertVariableNameProperty(strxxx &pVariableName, EXTfldval &pDst);	// rmm8135
	static void jsInsertVariableNameProperty(EXTfldval &pVariableName, EXTfldval &pDst);	// rmm8135
	static void jsInsertVariableNamePropertyWithAttName(strxxx & pVariableName, EXTfldval & pDst, strxxx &pAttName); // dmw0233
	static void jsInsertVariableNamePropertyWithAttName(EXTfldval & pVariableName, EXTfldval & pDst, strxxx &pAttName); // dmw0233
	static void jsInsert(qlong insertLong, EXTfldval& dst);
	static void jsInsertOuterHtml(EXTCompInfo* eci, HWND pHwnd, JSCcontrol* pControl, EXTfldval& pOuter, qdim& pWidth, qdim& pHeight);	// rmm7081 // rmm7082
	// Start rmm7058: renamed append rather than insert
	static void jsStyleAppendFontStyle(qlong pStyle, EXTfldval& dst);
	static void jsStyleAppendFontSize(qlong pSize, EXTfldval& dst);
	static void jsStyleAppendFontName(EXTfldval& insertStr, EXTfldval& dst);
	// End rmm7058
	static void jsStyleAppendFontAlign(qlong pAlignValue, EXTfldval &dst);	// rmm7076
	static void jsStyleAppendInnerPosition(EXTfldval &style, qdim padding, qdim pWidth, qdim pHeight); // rmm7076
	static void jsInsertBorder(HWND pHwnd, EXTfldval &pDest);	// rmm7078
	
	static void jsStyleAppendColor(HWND pHwnd, attnumber pColorAnum, EXTfldval& dst, attnumber pAlphaComponent = 0); // rmm7058
	static void jsStyleAppendColorFromValue(HWND pHwnd, qcol pColorValue, EXTfldval &dst, qlong pAlpha = -1);	// rmm7079 // rmm7101
	static void jsInsertColorPair(HWND pHwnd, EXTfldval &pDest, qcol pColor, qlong pAlpha); // rmm7101
	
	static void jsGetFontName(HWND pHwnd, EXTfldval &pFontNameFval, qlong pFont = -1, qlong pFontsize = -1);	// rmm7056	//CRJSCal
	static void jsGetNumericProperty(HWND pHwnd, attnumber pAnum, strxxx &pString);
	static void jsGetId(HWND pHwnd, str255& str, qbool pFrame);	// CR0010
	static void jsInsertId(HWND pHwnd, EXTfldval &pDest, qbool pFrame, strxxx *pSuffix = 0); // rmm7095
	// [[deprecated]]
	inline static void jsInsertStyle(HWND pHwnd, WCCcontrol* pControl, EXTfldval& pDest, qdim pWidth, qdim pHeight, javaScriptComponent* pObject = 0) { // rmm7146
		jsInsertStyle(pHwnd, pControl->mHtmlOptions, pDest, pWidth, pHeight, pObject, pControl); // rmm10286
	}

	static void jsInsertDefaultAttributes(HWND pHwnd, EXTfldval& pDest, JSChtmlOptions* pOptions, javaScriptComponent* pObject); // jmg1035c // dmw0398: added new params, required for jssuper properties (currently just $horzpadding)
	void setOptionalBaseProperties(JSChtmlOptions* pOptions); // dmw0398
	virtual qbool propertyRequiresConversion(attnumber propID) { GDIignore(&propID); return false; } // dmw0398
	virtual void propertyHasBeenConverted(attnumber propID) { GDIignore(&propID); } // dmw0398

	virtual void setVersionedProperties() {}

	// Start rmm7999: More helper functions for building HTML
	static void jsInsertNum(const char *pAttName, qlong pValue, EXTfldval& dst, qbool allowZero = false); // jmg0256 // dmw0040
	static void jsInsertNum(const char *pAttName, qreal pValue, qshort dp, EXTfldval& dst, qbool allowZero = qfalse); // jmg0909
	static void jsInsertIcon(HWND pHwnd, const char* pAttName, EXTfldval& pIconId, EXTfldval& dst); // rmm_svg2
	static void jsInsertBool(const char *pAttName, qbool pValue, EXTfldval& dst); // jmg0256
	// End rmm7999
	static void jsInsertColor(const char *pAttName, qcol pColor, EXTfldval &pDst);	// rmm8451 // jmg0256
	static void jsInsertColorWithAlpha(const char *pAttName, qcol pColor, EXTfldval &pDst, qlong pAlpha); // bjw0431
	static void jsInsertColorPairAttribute(HWND pHwnd, const char *pAttName, qcol pColor, EXTfldval& dst, qlong pAlpha = -1); // jmg0068 // jmg0256
	static void jsInsertDragMode(javaScriptComponent *pObject, EXTfldval &pDst);		// rmm8700
	static void jsInsertHiliteLine(javaScriptComponent *pObject, EXTfldval &pDst);	// rmm8700
	static void jsInsertBorderIcon(javaScriptComponent *pObject, EXTfldval &pDst); // bjw0793

	/*** Generic getter/setter functions ***/ // Start jmg0111
	qbool getQcolProp(EXTfldval* fval, const qcol var);
	qbool setQcolProp(EXTfldval* fval, qcol* var, qbool invalidate = qfalse);
	qbool getQShortProp(EXTfldval* fval, const qshort var);
	qbool setQShortProp(EXTfldval* fval, qshort* var, qbool invalidate = qfalse, qbool limit = qfalse); // dmw0040
	qbool setQShortProp(EXTfldval* fval, qshort* var, qbool invalidate, qshort limit); // dmw0040 // bjw0048
	qbool getQLongProp(EXTfldval* fval, const qlong var);
	qbool setQLongProp(EXTfldval* fval, qlong* var, qbool invalidate = qfalse);
	// End jmg0111
	qbool getQBoolProp(EXTfldval * fval, const qbool var); // jmg0626a
	qbool setQBoolProp(EXTfldval * fval, qbool * var, qbool invalidate = qfalse); // jmg0626a
	qbool getQNumProp(EXTfldval * fval, const qreal var); // jmg0909
	qbool setQNumProp(EXTfldval * fval, qreal* var, qbool invalidate = qfalse); // jmg0909
	
	static qbool setQLongProp(EXTfldval* fval, qlong* var, qlong min, qlong max, javaScriptComponent* component = NULL, qbool invalidate = qfalse); // jmg0494

	static void escapeHTMLsyntaxChars(EXTfldval &pFval, EXTfldval &pEscapedFval);	// rmm7216


	virtual qbool eraseBackground(WPARAM wParam, LPARAM lParam) { if (mUseDefaultEraseBackground) defaultEraseBackground(wParam, lParam); return qtrue; } // rmm8441
	virtual qlong attributeSupport(LPARAM pMessage, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci) override { GDIignore(&pMessage); GDIignore(&wParam); GDIignore(&lParam); GDIignore(&eci); return qfalse; } // rmm7072: qfalse means nothing was processed (was qtrue)
	
	void defaultEraseBackground(WPARAM wParam, LPARAM lParam);	// rmm8441

	virtual attnumber getHorzPaddingPropID() { return cBaseHorzPaddingID; } // dmw0398
	virtual qlong getDefaultHorzPaddingValue() { return cBaseDefaultHorzPadding; } // dmw0398

	virtual attnumber getVertPaddingPropID() { return cBaseVertPaddingID; } // dmw0407
	virtual qlong getDefaultVertPaddingValue() { return cBaseDefaultVertPadding; } // dmw0407
	

	protected:
		virtual qbool getInnerHtml(EXTfldval& pInnerHtml, qdim pWidth, qdim pHeight);
		virtual qbool amendHtmlStyles(WCCcontrol *pLegacyControl, EXTfldval& style); ///< Override to add extra style attributes to the client HTML elem // rmm10286

		void jsInsertStyle(EXTfldval& pDest, qdim pWidth, qdim pHeight);

		/**
		 Replaces the first "$" in pInnerHtml with attributes for the id, style and border.
		 */
		qbool setInnerHtmlStandardAttribs(EXTfldval& pInnerHtml, qdim width, qdim height);

		/**
		 Replaces the first "$" in pInnerHtml with attributes for all of the control's InnerHtmlDefs.
		 */
		qbool setInnerHtmlProperties(EXTfldval& pInnerHtml);	

		private:
			omnisComponent_formatNotation* createFormatNotationClass() override;
			qbool hasFormatNotationClass() override;

};
typedef javaScriptComponent webClientComponent; // For backwards compatibility (we no longer have a webClientComponent)

// Class to use as the superclass of controls which have a list of items
class javaScriptComponentItemList : public javaScriptComponent
{
public:
	javaScriptComponentItemList(HWND pFieldHWnd, WCCcontrol *pControl, int pMaxItems, qbool pMustHaveItem = qtrue) : javaScriptComponent(pFieldHWnd, pControl) // rmm10726
	{ 
		mItemList = 0;
		mMaxItems = pMaxItems; 
		mMustHaveItem = pMustHaveItem;	// rmm10726
		// Create a single line item list, so there is always at least one item.
		// This is only necessary in design mode, so that the properties initialise correctly.
		newItemList(0); // TODO: Test this with a component which inherits from this class
	}
	
	javaScriptComponentItemList(HWND pFieldHWnd, JSCcontrol *pControl, int pMaxItems, qbool pMustHaveItem = qtrue, ComponentDelegate *pCompDelegate = 0) : javaScriptComponent(pFieldHWnd, pControl, pCompDelegate)
	{
		mItemList = 0;
		mMaxItems = pMaxItems;
		mMustHaveItem = pMustHaveItem;
		// Create a single line item list, so there is always at least one item.
		// This is only necessary in design mode, so that the properties initialise correctly.
		newItemList(0);
	}
};

// Flags for mWccFlags member of WCCcontrol
#define WCC_FLAG_CANFOCUS						0x1		// Set if the control accepts the focus
#define WCC_FLAG_USESCROLLVIEW			0x2		// Set if the scroll view is the view that takes the focus (used when we supply an OMBorderedView container)

// HTML generation options for JavaScript client control
// rmm9400: Removed mControlHasEvents as all our components always leave this set to true, and all controls have drop events
struct JSChtmlOptions
{
public:
	JSChtmlOptions()
	{
		mInnerStylePositionIsRelative = qfalse;
		mInnerStyleHasFont = qtrue;
		mInnerStyleHasTextColor = qtrue;
		mInnerStyleHasBackgroundColor = qtrue;
		mInnerStylePadding = 0;
		mInnerStyleHasScrollbars = qfalse;
		mInnerStyleHasAlign = qtrue;
		mInnerStyleHasNoWrap = qtrue;
		mControlHasDataName = qtrue;
		mAdjustWidthHeightForBorder = qfalse;
		mHasHorzPadding = qfalse; // dmw0398
		mHasVertPadding = qfalse; // dmw0407
		mHasDatePickerOptions = qfalse; // dmw0522
		mHasEnterToDoubleClick = qfalse; // dmw0526
		mHasVertAlign = qfalse; // bjw0569
		mHasSplitIconAndText = qfalse; // bjw0569
		mHasIconTextSpacing = qfalse; // bjw0569
		mHasReorderMode = qfalse; // bjw0686
		mHasRightClickSetsLine = qfalse; // bjw0771
	}

	qbool		mInnerStylePositionIsRelative;
	qbool		mInnerStyleHasFont;
	qbool		mInnerStyleHasTextColor;
	qbool		mInnerStyleHasBackgroundColor;
	qbyte		mInnerStylePadding;  // mpmPopMenu2 was qbool
	qbool		mInnerStyleHasScrollbars;
	qbool		mInnerStyleHasAlign;
	qbool		mInnerStyleHasNoWrap;
	qbool		mControlHasDataName;
	qbool		mAdjustWidthHeightForBorder;
	str255	mInnerStyleExtra;		// extra style setting to be appended // mpmPopMenu2
	qbool		mHasHorzPadding; // dmw0398
	qbool		mHasVertPadding; // dmw0407
	qbool 	mHasDatePickerOptions; // dmw0522
	qbool		mHasEnterToDoubleClick; // dmw0526
	qbool		mHasVertAlign; // bjw0569
	qbool		mHasSplitIconAndText; // bjw0569
	qbool		mHasIconTextSpacing; // bjw0569
	qbool		mHasReorderMode; // bjw0686
	qbool		mHasRightClickSetsLine; // bjw0771
	qbool		mHasBorderIconStyle; // bjw0793
};
// End rmm7082

enum autoPropType {
	autoPropCharacter = fftCharacter,
	autoPropInteger = fftInteger,
	autoPropReal = fftNumber,
	autoPropBool = fftBoolean,
	autoPropColor,
	autoPropIcon,
	autoPropColorAlpha = 100, // bjw0431
	autoPropFont = 101 // bjw0465
};

struct InnerHtmlDef {
	attnumber mAnum;						///< The property number.
	autoPropType mType;					///< The type of the data.
	const char* mAttribute;			///< The attribute name. non-standard attribs should be prefixed with "data-".
	qlong	mFlags;								///< For future use.
};

struct OmnisJSControlDefinition {
	qlong								mCompFlags;					// Flags sent in response to ECM_IPHONE_OR_JAVASCRIPT_COMPFLAGS
	qlong								mWccFlags;					// WCC_FLAG_... flags
	JSChtmlOptions* mHtmlOptions;						// rmm7082: JavaScript client HTML options
	InnerHtmlDef* mInnerHtmlDefs;						// Table of properties to automatically add as attrinutes in the control's inner HTML.
	qshort mInnerHtmlDefCount;							// Number of entries in mInnerHtmlDefs
	const char* mJscCtrlName;								// rmm7082: JavaScript client control name (no spaces etc)
	attnumber					mControlNameAnum;			// Attribute for control name when mJscCtrlName is to be overridden

};


/** The static definition of a JS Component type. Comprises a base Omnis component definition, and JS-specific definition.
Also may include a legacy WCCcontrol pointer, if it is an old-style component based on a WCCcontrol */
struct JSCcontrol {
	OMNISControlDefinition mOmnisControlDef;
	OmnisJSControlDefinition mJSControlDef;
	WCCcontrol* mLegacyWCCcontrolDef;
};


// [deprecated] Legacy WndProc for JavaScript controls - new components should avoid this.
LRESULT JSCdefWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci, WCCcontrol* pControl); // rmm64bit5: UINT, LRESULT

// Default WndProc for JavaScript controls
LRESULT JSCdefWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci, JSCcontrol* pControl);


#endif	// #ifndef _JSSUPER_H_
// End of file
