{***************************************************************************}
{ TMS IntraWeb Component Pack Pro                                           }
{ for Delphi & C++Builder                                                   }
{ version 2.5                                                               }
{                                                                           }
{ written by TMS Software                                                   }
{            copyright © 2002 - 2009                                        }
{            Email : info@tmssoftware.com                                   }
{            Web : http://www.tmssoftware.com                               }
{                                                                           }
{ The source code is given as is. The author is not responsible             }
{ for any possible damage done due to the use of this code.                 }
{ The component can be freely used in any application. The complete         }
{ source code remains property of the author and may not be distributed,    }
{ published, given or sold in any form as such. No parts of the source      }
{ code can be included in any other component or application without        }
{ written authorization of the author.                                      }
{***************************************************************************}

unit IWTMSMenus;

{$I TMSDEFS.INC}
                                                     
interface                                                        
{$R tmsiwmenuxp.res}
uses
  {$IFDEF LINUX}
  QControls, QGraphics, QIWPicCntnr, QMenus,
  {$ELSE}
  Controls, Windows, Graphics, IWPicCntnr, IWTMSImg, Menus,
  {$ENDIF}                                                           
  {$IFDEF DELPHI6_LVL}
  Types,
  {$ENDIF}                                                              
  {$IFDEF TMSIW51}
  IWColor,
  {$ENDIF}
  Classes, IWControl, IWTypes, SysUtils, IWHTMLTag,
  IWCompEdit, IWCompLabel, IWCompCheckBox, IWExtCtrls, IWTMSBase,
  dialogs, IWFont
  {$IFDEF TMSIW6}
  , IWRenderContext
  {$ENDIF}
  {$IFDEF TMSIW9}
  , IWXMLTag
  {$ENDIF}
  ;
type
  TStaticMenuLayout = (smlVertical,smlHorizontal);

  TIWMenuClickEvent = procedure(Sender: TObject; ItemIdx: Integer) of object;
  TTIWGradientDirection = (gdHorizontal, gdVertical);
  TTIWFade = (fdNone,fdSlow,fdMedium,fdFast);

  {$IFDEF TMSIW9}
  TIWAsyncMenuEvent = procedure (Sender: TObject; EventParams: TStringList; AMenuItem: TMenuItem) of object;
  TIWAsyncItemEvent = procedure (Sender: TObject; EventParams: TStringList; SelectedIndex: Integer) of object;
  {$ENDIF}

//  TTIWTextAlign = (taLeft,taCenter,taRight);

  TTIWStaticMenu = class;

  TTIWStaticMenuItem = class(TCollectionItem)
  private
    FCaption: string;
    FClientClick: string;
    FFixed: Boolean;
    FTag: string;
    procedure SetCaption(Value: string);
  protected
  public
    procedure Assign(Source: TPersistent); override;
  published
    property Caption: string read FCaption write SetCaption;
    property ClientClick: string read FClientClick write FClientClick;
    property Fixed: Boolean read FFixed write FFixed;
    property Tag: string read FTag write FTag;
  end;

  TTIWStaticMenuItems = class(TCollection)
  private
    FOwner: TTIWStaticMenu;
    function GetItem(Index: Integer): TTIWStaticMenuItem;
    procedure SetItem(Index: Integer; const Value: TTIWStaticMenuItem);
  public
    function Add: TTIWStaticMenuItem;
    function Insert(index: Integer): TTIWStaticMenuItem;
    property Items[Index: Integer]: TTIWStaticMenuItem read GetItem write SetItem; default;
    constructor Create(AOwner: TTIWStaticMenu);
  end;

  TTIWStaticMenu = class(TIWControl)
  private
    ic: TIWHTMLPictureCache;
    FItems: TTIWStaticMenuItems;
    FColor: TIWColor;
    FColorTo: TIWColor;
    FColorGradientDirection: TTIWGradientDirection;
    FHoverColor: TIWColor;
    FHoverColorTo: TIWColor;
    FHoverColorGradientDirection: TTIWGradientDirection;
    FHoverFontColor: TIWColor;
    FLayout: TStaticMenuLayout;
    FBorderColor: TIWColor;
    FHoverBorderColor: TIWColor;
    FHoverBorderShadow: Boolean;
    FDesignMode: Boolean;
    FOnClick: TIWMenuClickEvent;
    FDesignLive: Boolean;
    FBaseDir: string;
    FItemHeight: integer;
    FShowSelected: Boolean;
    FSelectedIndex: Integer;
    FSelectedColor: TIWColor;
    FSelectedColorTo: TIWColor;
    FSelectedColorGradientDirection: TTIWGradientDirection;
    FSelectedFontColor: TIWColor;
    FFixedColor: TIWColor;
    FFixedColorTo: TIWColor;
    FFixedColorGradientDirection: TTIWGradientDirection;
    FFixedFontColor: TIWColor;
    FFixedBorderColor: TIWColor;
    {$IFDEF TMSIW9}
    FOnAsyncItemClick: TIWAsyncItemEvent;
    {$ENDIF}
    procedure SetColor(const Value: TIWColor);
    procedure SetColorTo(const Value: TIWColor);
    procedure SetHoverColor(const Value: TIWColor);
    procedure SetHoverColorTo(const Value: TIWColor);
    procedure SetLayout(const Value: TStaticMenuLayout);
    procedure SetBorderColor(const Value: TIWColor);
    procedure SetHoverBorderColor(const Value: TIWColor);
    {$IFNDEF TMSIW71}
    procedure SetDesignMode(const Value: Boolean);
    {$ENDIF}
    procedure SetBaseDir(const Value: string);
    procedure SetDesignLive(const Value: Boolean);
    procedure SetItemHeight(const Value: Integer);
  protected
    procedure Submit(const AValue: string); override;
    procedure ItemsChanged(Sender: TObject);
    function HTMLClr(Color: TIWColor): string;
    {$IFDEF TMSIW9}
    procedure DoAsyncItemClick(AParams: TStringList);
    {$ENDIF}
  public
    {$IFDEF TMSIW6}
    procedure IWPaint; override;
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    {$ELSE}
    procedure Paint; override;
    function RenderHTML: TIWHTMLTag; override;
    {$ENDIF}
    {$IFDEF TMSIW9}
    function RenderAsync(AContext: TIWBaseHTMLComponentContext): TIWXMLTag; override;
    {$ENDIF}    
    procedure SetValue(const value:string); override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property BaseDir: string read FBaseDir write SetBaseDir;
    property DesignLive: Boolean read FDesignLive write SetDesignLive;
    property BorderColor: TIWColor read FBorderColor write SetBorderColor;
    property Color: TIWColor read FColor write SetColor default clWhite;
    property ColorTo: TIWColor read FColorTo write SetColorTo default clNone;
    property ColorGradientDirection: TTIWGradientDirection read FColorGradientDirection write FColorGradientDirection;
    {$IFNDEF TMSIW71}
    property DesignMode: Boolean read FDesignMode write SetDesignMode;
    {$ENDIF}
    property Font;
    property HoverBorderColor: TIWColor read FHoverBorderColor write SetHoverBorderColor;
    property HoverBorderShadow: Boolean read FHoverBorderShadow write FHoverBorderShadow default false;
    property HoverColor: TIWColor read FHoverColor write SetHoverColor;
    property HoverColorTo: TIWColor read FHoverColorTo write SetHoverColorTo;
    property HoverColorGradientDirection: TTIWGradientDirection read FHoverColorGradientDirection write FHoverColorGradientDirection;
    property HoverFontColor: TIWColor read FHoverFontColor write FHoverFontColor;
    property ItemHeight : integer read FItemHeight write SetItemHeight;
    property Items: TTIWStaticMenuItems read FItems write FItems;
    property Layout: TStaticMenuLayout read FLayout write SetLayout;
    property OnClick: TIWMenuClickEvent read FOnClick write FOnClick;
    property ShowSelected: Boolean read FShowSelected write FShowSelected default false;
    property SelectedIndex: Integer read FSelectedIndex write FSelectedIndex default -1;
    property SelectedColor: TIWColor read FSelectedColor write FSelectedColor default clInfoBk;
    property SelectedColorTo: TIWColor read FSelectedColorTo write FSelectedColorTo default clNone;
    property SelectedColorGradientDirection: TTIWGradientDirection read FSelectedColorGradientDirection write FSelectedColorGradientDirection default gdHorizontal;
    property SelectedFontColor: TIWColor read FSelectedFontColor write FSelectedFontColor default clBlack;
    property FixedColor: TIWColor read FFixedColor write FFixedColor default clWhite;
    property FixedColorTo: TIWColor read FFixedColorTo write FFixedColorTo default clNone;
    property FixedColorGradientDirection: TTIWGradientDirection read FFixedColorGradientDirection  write FFixedColorGradientDirection default gdHorizontal;
    property FixedFontColor: TIWColor read FFixedFontColor write FFixedFontColor default clBlack;
    property FixedBorderColor: TIWColor read FFixedBorderColor write FFixedBorderColor default clNone;
    {$IFDEF TMSIW9}
    property OnAsyncItemClick: TIWAsyncItemEvent read FOnAsyncItemClick write FOnAsyncItemClick;
    {$ENDIF}
  end;

  TMenuClientEvent = class(TCollectionItem)
  private
    FItemName: string;
    FItemScript: string;
  public
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
    procedure Assign(source: TPersistent); override;
  
  published
    property ItemName: string read FItemName write FItemName;
    property ItemScript: string read FItemScript write FItemScript;
  end;

  TMenuClientEvents = class(TCollection)
  private
    function GetItem(Index: Integer): TMenuClientEvent;
    procedure SetItem(Index: Integer; const Value: TMenuClientEvent);

  public
    constructor Create;
    function Add: TMenuClientEvent;
    function Insert(index: Integer): TMenuClientEvent;
    function IndexOf(ItemName: string): Integer;
    property Items[Index: Integer]: TMenuClientEvent read GetItem write SetItem; default;
  end;

  TIWMenuOpen = (moHover,moClick);

  TTIWMainMenu = class(TIWControl)
  private
    FAutoHiding : Boolean;
    FBackgroundImage: TIPicture;
    FBorder: Boolean;
    FBorderColor: TIWColor;
    FClientEvents: TMenuClientEvents;
    FFade : TTIWFade;
    FHoverBorderColor: TIWColor;
    FHoverColor: TIWColor;
    FHoverColorTo : TIWColor;
    FHoverFontColor: TIWColor;
    FHoverGradientDirection : TTIWGradientDirection;
    FIconBackgroundColor : TIWColor;
    FIconBackgroundColorTo : TIWColor;
    FItemColor : TIWColor;
    FItemHeight : Integer;
    FItemSpacing: Integer;
    FMenu: TMenu;
    FOpacity : Integer;
    FOpen: TIWMenuOpen;
    FRootItemBorderColor : TIWColor;
    FRootItemBorderHoverColor : TIWColor;
    FRootItemBorderWidth : integer;
    FRootItemColor : TIWColor;
    FRootItemColorTo : TIWColor;
    FRootItemHoverColor : TIWColor;
    FRootItemHoverColorTo : TIWColor;
    FRootItemDownColor : TIWColor;
    FRootItemDownColorTo : TIWColor;
    FRootItemFont : TIWFont;
    FRootItemGradientDirection : TTIWGradientDirection;
    FRootItemHoverFontColor : TIWColor;
    FSeparatorColor : TIWColor;
    FShowIcons : Boolean;
    FSubMenuGlyph: TIPicture;
    FTextAlignment : TAlignment;
    FUseBorder : Boolean;

    FDesignMode: Boolean;

    arMenuId : TStringList;
    arMenuName : TStringList;
    Tiers : TStringList;
    MenuCode : string;
    Level : integer;
    AutoNumber : integer;
    FCacheDir : string;
    FSelectedItem: string;

    {$IFDEF TMSIW9}
    FOnAsyncMenuClick: TIWAsyncMenuEvent;
    procedure DoAsyncMenuClick(AParams: TStringList);
    {$ENDIF}
    function StringToMenuItem(Value: string) : TMenuItem;

    procedure BackgroundChanged(Sender: TObject);
    procedure SetAutoHiding(const Value : boolean);
    procedure SetBackgroundImage(const Value: TIPicture);
    {$IFNDEF TMSIW71}
    procedure SetDesignMode(const Value: Boolean);
    {$ENDIF}
    procedure SetFade(const Value : TTIWFade);
    procedure SetHoverGradientDirection(const Value : TTIWGradientDirection);
    procedure SetIconBackgroundColor(const Value : TIWColor);
    procedure SetIconBackgroundColorTo(const Value : TIWColor);
    procedure SetItemColor(const Value : TIWColor);
    procedure SetItemHeight(const Value : Integer);
    procedure SetMenu(const Value: TMenu);
    procedure SetOpacity(const Value : Integer);
    procedure SetRootItemBorderColor(const Value : TIWColor);
    procedure SetRootItemBorderHoverColor(const Value : TIWColor);
    procedure SetRootItemBorderWidth(const Value : integer);
    procedure SetRootItemColor(const Value: TIWColor);
    procedure SetRootItemColorTo(const Value: TIWColor);
    procedure SetRootItemDownColor(const Value : TIWColor);
    procedure SetRootItemDownColorTo(const Value : TIWColor);
    procedure SetRootItemFont(const Value : TIWFont);
    procedure SetRootItemGradientDirection(const Value : TTIWGradientDirection);
    procedure SetRootItemHoverColor(const Value : TIWColor);
    procedure SetRootItemHoverColorTo(const Value : TIWColor);
    procedure SetRootItemHoverFontColor(const Value : TIWColor);
    procedure SetTextAlignment(const Value : TAlignment);
    procedure SetSeparatorColor(const Value: TIWColor);
    procedure SetSubMenuGlyph(const Value: TIPicture);
    procedure SetUseBorder(const value : boolean);
    function FontToCSS(AFont : TIWFont; FromRoot : Boolean) : string;
    function TextAlignToStr(Alignment : TAlignment) : string;
    function MakeMenu(AName : string; AItem : TMenuItem) : string;
    procedure CacheDir;
    procedure DrawGradient(Canvas: TCanvas; FromColor, ToColor: TIWColor; Steps: Integer; r:TRect; Direction: Boolean);
  protected
    procedure Submit(const AValue: string); override;
    procedure SetValue(const value:string); override;    
    function HTMLClr(Color: TIWColor): string;
    function HTMLClrEx(Color: TIWColor): string;
    {$IFDEF TMSIW51}
    function CursorToHtml(Cursor : TIWCursor) : string;
    {$ELSE}
    function CursorToHtml(Cursor : TCursor) : string;
    {$ENDIF}
    function GradDirToStr(GradDir : TTIWGradientDirection) : string;
    function FadeToStr(FadeSpeed : TTIWFade) : string;
  public
    {$IFDEF TMSIW6}
    procedure IWPaint; override;
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    {$ELSE}
    procedure Paint; override;
    function RenderHTML: TIWHTMLTag; override;
    {$ENDIF}
    {$IFDEF TMSIW9}
    function RenderAsync(AContext: TIWBaseHTMLComponentContext): TIWXMLTag; override;
    {$ENDIF}    
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Invalidate; override;
  published
    property AutoHiding : boolean read FAutoHiding write SetAutoHiding;
    property BackgroundImage: TIPicture read FBackgroundImage write SetBackgroundImage;
    property Border: Boolean read FBorder write FBorder;
    property BorderColor: TIWColor read FBorderColor write FBorderColor;
    property Caption;
    property ClientEvents: TMenuClientEvents read FClientEvents write FClientEvents;
    property Color;
    {$IFNDEF TMSIW71}
    property DesignMode: Boolean read FDesignMode write SetDesignMode;
    {$ENDIF}
    property Fade : TTIWFade read FFade write SetFade;
    property Font;
    property HoverBorderColor: TIWColor read FHoverBorderColor write FHoverBorderColor;
    property HoverColor: TIWColor read FHoverColor write FHoverColor;
    property HoverColorTo : TIWColor read FHoverColorTo write FHoverColorTo;
    property HoverFontColor: TIWColor read FHoverFontColor write FHoverFontColor;
    property HoverGradientDirection : TTIWGradientDirection read FHoverGradientDirection write SetHoverGradientDirection;
    property IconBackgroundColor : TIWColor read FIconBackgroundColor write SetIconBackgroundColor;
    property IconBackgroundColorTo : TIWColor read FIconBackgroundColorTo write SetIconBackgroundColorTo;
    property ItemColor : TIWColor read FItemColor write SetItemColor;
    property ItemHeight : Integer read FItemHeight write SetItemHeight;
    property ItemSpacing: Integer read FItemSpacing write FItemSpacing;
    property Menu: TMenu read FMenu write SetMenu;
    property Opacity : Integer read FOpacity write SetOpacity;
    property Open: TIWMenuOpen read FOpen write FOpen;
    property RootItemBorderColor : TIWColor read FRootItemBorderColor write SetRootItemBorderColor;
    property RootItemBorderHoverColor : TIWColor read FRootItemBorderHoverColor write SetRootItemBorderHoverColor;
    property RootItemBorderWidth : integer read FRootItemBorderWidth write SetRootItemBorderWidth;
    property RootItemColor : TIWColor read FRootItemColor write SetRootItemColor;
    property RootItemColorTo : TIWColor read FRootItemColorTo write SetRootItemColorTo;
    property RootItemHoverColor : TIWColor read FRootItemHoverColor write SetRootItemHoverColor;
    property RootItemHoverColorTo : TIWColor read FRootItemHoverColorTo write SetRootItemHoverColorTo;
    property RootItemDownColor : TIWColor read FRootItemDownColor write SetRootItemDownColor;
    property RootItemDownColorTo : TIWColor read FRootItemDownColorTo write SetRootItemDownColorTo;
    property RootItemFont : TIWFont read FRootItemFont write SetRootItemFont;
    property RootItemGradientDirection : TTIWGradientDirection read FRootItemGradientDirection write SetRootItemGradientDirection;
    property RootItemHoverFontColor : TIWColor read FRootItemHoverFontColor write SetRootItemHoverFontColor;
    property SeparatorColor : TIWColor read FSeparatorColor write SetSeparatorColor;
    property ShowIcons : Boolean read FShowIcons write FShowIcons;
    property SubMenuGlyph: TIPicture read FSubMenuGlyph write SetSubMenuGlyph;
    property TextAlignment : TAlignment read FTextAlignment write SetTextAlignment;
    property UseBorder : boolean read FUseBorder write SetUseBorder;
    {$IFDEF TMSIW9}
    property OnAsyncMenuClick: TIWAsyncMenuEvent read FOnAsyncMenuClick write FOnAsyncMenuClick;
    {$ENDIF}
  end;

  TTIWSideMenu = class(TIWControl)
  private
    FAutoHiding : Boolean;
    FBackgroundImage: TIPicture;
    FBorder: Boolean;
    FBorderColor: TIWColor;
    FClientEvents: TMenuClientEvents;
    FFade : TTIWFade;
    FHoverBorderColor: TIWColor;
    FHoverColor: TIWColor;
    FHoverColorTo : TIWColor;
    FHoverFontColor: TIWColor;
    FHoverGradientDirection : TTIWGradientDirection;
    FIconBackgroundColor : TIWColor;
    FIconBackgroundColorTo : TIWColor;
    FItemColor : TIWColor;
    FItemHeight : Integer;
    FItemSpacing: Integer;
    FMenu: TMenu;
    FOpacity : Integer;
    FOpen: TIWMenuOpen;
    FRootItemBorderColor : TIWColor;
    FRootItemBorderHoverColor : TIWColor;
    FRootItemBorderWidth : integer;
    FRootItemColor : TIWColor;
    FRootItemColorTo : TIWColor;
    FRootItemHeight : Integer;
    FRootItemHoverColor : TIWColor;
    FRootItemHoverColorTo : TIWColor;
    FRootItemDownColor : TIWColor;
    FRootItemDownColorTo : TIWColor;
    FRootItemFont : TIWFont;
    FRootItemGradientDirection : TTIWGradientDirection;
    FRootItemHoverFontColor : TIWColor;
    FSeparatorColor : TIWColor;
    FShowIcons : Boolean;
    FSubMenuGlyph: TIPicture;
    FTextAlignment : TAlignment;
    FUseBorder : Boolean;

    FDesignMode: Boolean;

    arMenuId : TStringList;
    arMenuName : TStringList;
    Tiers : TStringList;
    MenuCode : string;
    Level : integer;
    AutoNumber : integer;
    FCacheDir : string;
    FSelectedItem: string;

    {$IFDEF TMSIW9}
    FOnAsyncMenuClick: TIWAsyncMenuEvent;
    procedure DoAsyncMenuClick(AParams: TStringList);
    {$ENDIF}
    function StringToMenuItem(Value: string) : TMenuItem;

    procedure BackgroundChanged(Sender: TObject);
    procedure SetAutoHiding(const Value : boolean);
    procedure SetBackgroundImage(const Value: TIPicture);
    {$IFNDEF TMSIW71}
    procedure SetDesignMode(const Value: Boolean);
    {$ENDIF}
    procedure SetFade(const Value : TTIWFade);
    procedure SetHoverGradientDirection(const Value : TTIWGradientDirection);
    procedure SetIconBackgroundColor(const Value : TIWColor);
    procedure SetIconBackgroundColorTo(const Value : TIWColor);
    procedure SetItemColor(const Value : TIWColor);
    procedure SetItemHeight(const Value : Integer);
    procedure SetMenu(const Value: TMenu);
    procedure SetOpacity(const Value : Integer);
    procedure SetRootItemBorderColor(const Value : TIWColor);
    procedure SetRootItemBorderHoverColor(const Value : TIWColor);
    procedure SetRootItemBorderWidth(const Value : integer);
    procedure SetRootItemColor(const Value: TIWColor);
    procedure SetRootItemColorTo(const Value: TIWColor);
    procedure SetRootItemDownColor(const Value : TIWColor);
    procedure SetRootItemDownColorTo(const Value : TIWColor);
    procedure SetRootItemFont(const Value : TIWFont);
    procedure SetRootItemGradientDirection(const Value : TTIWGradientDirection);
    procedure SetRootItemHeight(const Value : integer);
    procedure SetRootItemHoverColor(const Value : TIWColor);
    procedure SetRootItemHoverColorTo(const Value : TIWColor);
    procedure SetRootItemHoverFontColor(const Value : TIWColor);
    procedure SetTextAlignment(const Value : TAlignment);
    procedure SetSeparatorColor(const Value: TIWColor);
    procedure SetSubMenuGlyph(const Value: TIPicture);
    procedure SetUseBorder(const value : boolean);
    function FontToCSS(AFont : TIWFont; FromRoot : Boolean) : string;
    function TextAlignToStr(Alignment : TAlignment) : string;
    function MakeMenu(AName : string; AItem : TMenuItem) : string;
    procedure CacheDir;
    procedure DrawGradient(Canvas: TCanvas; FromColor, ToColor: TIWColor; Steps: Integer; r:TRect; Direction: Boolean);
  protected
    procedure Submit(const AValue: string); override;
    procedure SetValue(const value:string); override;    
    function HTMLClr(Color: TIWColor): string;
    function HTMLClrEx(Color: TIWColor): string;
    {$IFDEF TMSIW51}
    function CursorToHtml(Cursor : TIWCursor) : string;
    {$ELSE}
    function CursorToHtml(Cursor : TCursor) : string;
    {$ENDIF}
    function GradDirToStr(GradDir : TTIWGradientDirection) : string;
    function FadeToStr(FadeSpeed : TTIWFade) : string;
  public
    {$IFDEF TMSIW6}
    procedure IWPaint; override;
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    {$ELSE}
    procedure Paint; override;
    function RenderHTML: TIWHTMLTag; override;
    {$ENDIF}
    {$IFDEF TMSIW9}
    function RenderAsync(AContext: TIWBaseHTMLComponentContext): TIWXMLTag; override;
    {$ENDIF}    
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property AutoHiding : boolean read FAutoHiding write SetAutoHiding;
    property BackgroundImage: TIPicture read FBackgroundImage write SetBackgroundImage;
    property Border: Boolean read FBorder write FBorder;
    property BorderColor: TIWColor read FBorderColor write FBorderColor;
    property Caption;
    property ClientEvents: TMenuClientEvents read FClientEvents write FClientEvents;
    property Color;
    {$IFNDEF TMSIW71}
    property DesignMode: Boolean read FDesignMode write SetDesignMode;
    {$ENDIF}
    property Fade : TTIWFade read FFade write SetFade;
    property Font;
    property HoverBorderColor: TIWColor read FHoverBorderColor write FHoverBorderColor;
    property HoverColor: TIWColor read FHoverColor write FHoverColor;
    property HoverColorTo : TIWColor read FHoverColorTo write FHoverColorTo;
    property HoverFontColor: TIWColor read FHoverFontColor write FHoverFontColor;
    property HoverGradientDirection : TTIWGradientDirection read FHoverGradientDirection write SetHoverGradientDirection;
    property IconBackgroundColor : TIWColor read FIconBackgroundColor write SetIconBackgroundColor;
    property IconBackgroundColorTo : TIWColor read FIconBackgroundColorTo write SetIconBackgroundColorTo;
    property ItemColor : TIWColor read FItemColor write SetItemColor;
    property ItemHeight : Integer read FItemHeight write SetItemHeight;
    property ItemSpacing: Integer read FItemSpacing write FItemSpacing;
    property Menu: TMenu read FMenu write SetMenu;
    property Opacity : Integer read FOpacity write SetOpacity;
    property Open: TIWMenuOpen read FOpen write FOpen;
    property RootItemBorderColor : TIWColor read FRootItemBorderColor write SetRootItemBorderColor;
    property RootItemBorderHoverColor : TIWColor read FRootItemBorderHoverColor write SetRootItemBorderHoverColor;
    property RootItemBorderWidth : integer read FRootItemBorderWidth write SetRootItemBorderWidth;
    property RootItemColor : TIWColor read FRootItemColor write SetRootItemColor;
    property RootItemColorTo : TIWColor read FRootItemColorTo write SetRootItemColorTo;
    property RootItemHeight : Integer read FRootItemHeight write SetRootItemHeight;
    property RootItemHoverColor : TIWColor read FRootItemHoverColor write SetRootItemHoverColor;
    property RootItemHoverColorTo : TIWColor read FRootItemHoverColorTo write SetRootItemHoverColorTo;
    property RootItemDownColor : TIWColor read FRootItemDownColor write SetRootItemDownColor;
    property RootItemDownColorTo : TIWColor read FRootItemDownColorTo write SetRootItemDownColorTo;
    property RootItemFont : TIWFont read FRootItemFont write SetRootItemFont;
    property RootItemGradientDirection : TTIWGradientDirection read FRootItemGradientDirection write SetRootItemGradientDirection;
    property RootItemHoverFontColor : TIWColor read FRootItemHoverFontColor write SetRootItemHoverFontColor;
    property SeparatorColor : TIWColor read FSeparatorColor write SetSeparatorColor;
    property ShowIcons : Boolean read FShowIcons write FShowIcons;
    property SubMenuGlyph: TIPicture read FSubMenuGlyph write SetSubMenuGlyph;
    property TextAlignment : TAlignment read FTextAlignment write SetTextAlignment;
    property UseBorder : boolean read FUseBorder write SetUseBorder;
    {$IFDEF TMSIW9}
    property OnAsyncMenuClick: TIWAsyncMenuEvent read FOnAsyncMenuClick write FOnAsyncMenuClick;
    {$ENDIF}
  end;

implementation

uses
  {$IFDEF LINUX}
  QImgList,
  {$ELSE}
  ImgList, ShellAPI, CommCtrl,
  {$ENDIF}
  IWApplication, IWServerControllerBase,
  SWStrings, SWSystem, IWAppForm, IWServer;

{$DEFINE REMOVESTRIP}
{$DEFINE REMOVEDRAW}

{$IFDEF LINUX}
 {$I QHTMLENG.PAS}
{$ELSE}
{$I iwhtmleng.pas}
{$ENDIF}

{$IFNDEF DELPHI7_LVL}
function BoolToStr(B: Boolean; UseBoolStrs: Boolean = False): string;
const
  cSimpleBoolStrs: array [boolean] of String = ('0', '-1');
begin
  Result := cSimpleBoolStrs[B];
end;
{$ENDIF}


{ TTIWMainMenu }
function TTIWMainMenu.StringToMenuItem(Value: string): TMenuItem;
var
  Decode, Sub: string;
  i,err: Integer;
  Menu: TMenuItem;
begin
  Menu := nil;

  Decode := Value;
  Delete(decode,1,length(HTMLName));

  if Assigned(FMenu) then
  begin
    Menu := nil;
    while length(decode) > 0 do
    begin
      sub := decode;
      if pos('_',sub) > 0 then
        Sub := copy(sub,1,pos('_',sub) - 1);
      val(sub,i,err);

      if (i > 0) then
      begin
        if Assigned(Menu) then
          Menu := Menu.Items[i - 1]
        else
          Menu := FMenu.Items[i - 1];
      end;

      delete(decode,1,length(sub) + 1);
    end;
  end;
  Result := Menu;
end;
{$IFDEF TMSIW9}
procedure TTIWMainMenu.DoAsyncMenuClick(AParams: TStringList);
begin
  if Assigned(OnAsyncMenuClick) then
    OnAsyncMenuClick(Self, AParams, StringToMenuItem(FSelectedItem));
end;

function TTIWMainMenu.RenderAsync(
  AContext: TIWBaseHTMLComponentContext): TIWXMLTag;
begin
  Result := TIWXMLTag.CreateTag('control');
  try
    Result.AddStringParam('id', HTMLName);
    Result.AddStringParam('type', 'TTIWMAINMENU');
    RenderAsyncCommonProperties( AContext, Result );
  except
    FreeAndNil(Result);
  end;
end;
{$ENDIF}

constructor TTIWMainMenu.Create(AOwner: TComponent);
begin
  inherited;
  {$IFDEF TMSIW6}
  {TODO}
  {$ELSE}
  FSupportsInput := True;
  FSupportsSubmit := True;
  {$ENDIF}
  FRootItemFont := TIWFont.Create;
  FRootItemFont.Size := 12;
  FRootItemFont.FontName := 'Verdana';
  FRootItemFont.Color := clBlack;
  Font.Color := clWindowText;
  Font.FontName := 'Verdana';
  Font.Size := 11;
  FAutoHiding := true;
  FBackgroundImage := TIPicture.Create;
  FBackgroundImage.OnChange := BackgroundChanged;
  FBorder := true;
  FClientEvents := TMenuClientEvents.Create;
  FDesignMode := True;
  FFade := fdNone;
  FHoverBorderColor := clHighlight;
  FHoverColor := $F0CAA6;
  FHoverColorTo := clNone;
  FHoverFontColor := clBlack;
  FHoverGradientDirection := gdHorizontal;
  FIconBackgroundColor := clBtnFace;
  FIconBackgroundColorTo := clNone;
  FItemColor := clWhite;
  FItemHeight := 20;
  FItemSpacing := 3;
  FOpacity := 100;
  FOpen := moClick;
  FRootItemColor := clBtnFace;
  FRootItemColorTo := clNone;
  FRootItemBorderColor := clBtnFace;
  FRootItemBorderWidth := 1;
  FRootItemGradientDirection := gdHorizontal;
  FRootItemHoverFontColor := clBlack;
  FRootItemHoverColor := clNone;
  FRootItemHoverColorTo := clNone;
  FRootItemDownColor := clNone;
  FRootItemDownColorTo := clNone;
  FRootItemBorderHoverColor := clNone;
  FSeparatorColor := clBtnFace;
  FSubMenuGlyph := TIPicture.Create;
  FUseBorder := true;
  FShowIcons := true;
  FTextAlignment := taLeftJustify;
  Self.Height := 20;
  Self.Width := 200;
  Self.BorderColor := clBtnFace;
  Self.Color := clBtnFace;
  Zindex := 10;

  arMenuId := TStringList.Create;
  arMenuName := TStringList.Create;
  Tiers := TStringList.Create;
  MenuCode := '';
  Level := 0;
  AutoNumber := 0;
  FCacheDir := '';

  if not (csDesigning in Componentstate) then
  begin
    {$IFDEF TMSIW51}
    TIWServer.AddInternalFile('IW_JS_TMSMENU','/js/TMSMENU.js');
    TIWServer.AddInternalFile('IW_JS_TMSMENUSETTINGS','/js/TMSMENUSETTINGS.js');
    TIWServer.AddInternalFile('IW_JS_TMSMENUUTIL','/js/TMSMENUUTIL.js');
    {$ELSE}
    GIWServer.AddInternalFile('IW_JS_TMSMENU');
    GIWServer.AddInternalFile('IW_JS_TMSMENUSETTINGS');
    GIWServer.AddInternalFile('IW_JS_TMSMENUUTIL');
    {$ENDIF}
  end;
  {$IFDEF TMSIW7}
  SupportsPartial := true;
  {$ENDIF}
end;

procedure TTIWMainMenu.Invalidate;
begin
  inherited; 
end;

destructor TTIWMainMenu.Destroy;
begin
  FClientEvents.Free;
  FSubMenuGlyph.Free;
  FBackgroundImage.Free;
  FRootItemFont.Free;
  arMenuId.Free;
  arMenuName.Free;
  Tiers.Free;
  inherited;
end;

function TTIWMainMenu.HTMLClr(color: TIWColor):string;
begin
  Result := ColorToRGBString(ColorToRGB(color));
end;

function TTIWMainMenu.HTMLClrEx(color: TIWColor):string;
begin
  if (color = clNone) then
    Result := ''
  else
    Result := ColorToRGBString(ColorToRGB(color));
end;

{$IFDEF TMSIW51}
function TTIWMainMenu.CursorToHtml(Cursor : TIWCursor):string;
{$ELSE}
function TTIWMainMenu.CursorToHtml(Cursor : TCursor):string;
{$ENDIF}
begin
  case Cursor of
    {$IFDEF TMSIW51}
    crCrossHair: Result := 'crosshair';
    crDefault: Result := 'default';
    crWait: Result := 'wait';
    crAuto: Result := 'auto';
    crPointer: Result := 'pointer';
    crMove: Result := 'move';
    crEResize: Result := 'e-resize';
    crNEResize: Result := 'ne-resize';
    crNWResize: Result := 'nw-resize';
    crNResize: Result := 'n-resize';
    crSEResize: Result := 'se-resize';
    crSWResize: Result := 'sw-resize';                   
    crSResize: Result := 's-resize';
    crWResize: Result := 'w-resize';
    crText: Result := 'text';
    crHelp: Result := 'help';
    {$ELSE}
    crAppStart : Result := 'wait';
    crCross : Result := 'crosshair';
    crDefault : Result := 'default';
    crHandPoint : Result := 'pointer';
    crHelp : Result := 'help';
    crHourGlass : Result := 'wait';
    criBeam : Result := 'auto';
    crSizeAll : Result := 'move';
    crSizeNESW : Result := 'ne-resize';
    crSizeNS : Result := 'n-resize';
    crSizeNWSE : Result := 'nw-resize';
    crSizeWE : Result := 'e-resize';
    {$ENDIF}
  else
    Result := 'default';
  end;
end;

function TTIWMainMenu.GradDirToStr(GradDir : TTIWGradientDirection) : string;
begin
  if GradDir = gdHorizontal then
    Result := '1'
  else
    Result := '0';
end;

function TTIWMainMenu.FadeToStr(FadeSpeed : TTIWFade) : string;
begin
  case FadeSpeed of
    fdNone : Result := '0';
    fdSlow : Result := '10';
    fdMedium : Result := '7';
    fdFast : Result := '4';
  else
    Result := '0';
  end;
end;

function TTIWMainMenu.FontToCSS(AFont : TIWFont; FromRoot : Boolean) : string;
var
  Weight, Res : string;
begin
  Weight := '';
  Res := '';

  if fsBold in AFont.Style then
    Weight := #13'font-weight: bold;'#13;

  if (FromRoot) then
  begin
    if (AFont.FontName <> '') then
      Res := Res
        + '  font-family:' + AFont.FontName + ';'#13;

    if (fsItalic in AFont.Style) then
      Res := Res
        + ' font-style:italic;'#13;
        
    Res := Res
      + '  color:' + HTMLClr(FRootItemFont.Color) + ';'#13
      + Weight
      + '  font-size:' + IntToStr(AFont.Size) + ';'#13;
  end
  else
  begin
    if (AFont.FontName <> '') then
      Res := '  font-family:' + AFont.FontName + ';'#13;

    if (AFont.Color <> clNone) then
      Res := Res
        + '  color:' + HTMLClr(AFont.Color) + ';'#13
    else
      Res := Res
        + '  color:black;'#13;

    if (fsItalic in AFont.Style) then
      Res := Res
        + ' font-style:italic;'#13;

    Res := Res
      + Weight
      + '  font-size:' + IntToStr(AFont.Size) + ';'#13;
  end;
  Result := Res;
end;

function TTIWMainMenu.TextAlignToStr(Alignment : TAlignment) : string;
begin
  case Alignment of
    taLeftJustify:
      Result := 'text-align:left;';
    taCenter:
      Result := 'text-align:center;';
    taRightJustify:
      Result := 'text-align:right;';
    else
      Result := 'text-align:left;';
  end;
end;

function TTIWMainMenu.MakeMenu(AName : string; AItem : TMenuItem) : string;
var
  i, l, x, Idx : integer;
  Name, CleanedID, URLBack, URL, ItemSP, IconColorTo, Cap : string;
  ID : array of integer;
  UseImage : boolean;
  SubItem : TMenuItem;
  BMP : TBitmap;

begin
  //ID = new int[AItem.SubMenu.Count];
  SetLength(ID,AItem.Count);

  CleanedID := HTMLName;

  if (AItem.Count > 0) then
  begin
    if (Tiers.Count = 0) then
    begin
      for l := 0 to StrToInt(AName)- 1 do
        Tiers.Add('null');

      Tiers.Add(IntToStr(Level));
    end
    else
    begin
      if (StrToInt(AName) > Tiers.Count) then
      begin
        for x := Tiers.Count to StrToInt(AName) - 1 do
          Tiers.Add('null');

        Tiers.Add(IntToStr(Level));
      end
      else
      begin
        if (StrToInt(AName) = Tiers.Count) then
          Tiers.Add(IntToStr(Level))
        else
          Tiers[StrToInt(AName)] := IntToStr(Level);
      end;
    end;

    Idx := arMenuId.IndexOf(AName);
    URLBack := '';
    useImage := false;

//    for I := 0 to arMenuId.Count - 1 do
//      OutputDebugString(pchar('arMenuID: ' + arMenuId[i]));

    if not (FBackgroundImage.Empty) then
    begin
      UseImage := true;

      if FBackgroundImage.IsGIF then
      {$IFDEF TMSIW71}
      URLBack := TIWServerControllerBase.NewCacheFile('gif',true)
      {$ELSE}
      URLBack := TIWServerControllerBase.NewCacheFile('gif')
      {$ENDIF}
      else
      {$IFDEF TMSIW71}
      URLBack := TIWServerControllerBase.NewCacheFile('jpg',true);
      {$ELSE}
      URLBack := TIWServerControllerBase.NewCacheFile('jpg');
      {$ENDIF}

      FBackgroundImage.SaveToFile(URLBack);
      URLBack := FCacheDir + ExtractFileName(URLBack);
    end;

    MenuCode := MenuCode
      + #13
      + 'startMenu(' + AName + ',150,' + IntToStr(Level) + ',''' + HTMLClr(FBorderColor) + ''','''
      + CleanedID + '_' + arMenuName[Idx] + ''',''' + IntToStr(100+ZIndex) + ''','''
      + URLBack + ''',''' + IntToStr(Opacity) + ''');'#13;

//OutputDebugString(pchar('startmenu: ' + CleanedID + '# menuname:' + arMenuName[Idx]
//+ ' **IDCount: ' + IntToStr(arMenuId.Count) + ' §§Index: ' + IntToStr(Idx)));

    for i := 1 to AItem.Count do
    begin
      SubItem := AItem.Items[i-1];
      URL := '';

      if (SubItem.Visible) then
      begin

        if (SubItem.ImageIndex >= 0) and Assigned(FMenu.Images) and not (SubItem.Checked) then
        begin
          if (FMenu.Images.Count > SubItem.ImageIndex) then
          begin
            BMP := TBitmap.Create;
            FMenu.Images.BkColor := FIconBackgroundColor;
            FMenu.Images.GetBitmap(SubItem.ImageIndex,BMP);
            //URL := HTMLBmp(BMP);
            URL := '';
            {$IFDEF TMSIW71}
            URL := TIWServerControllerBase.NewCacheFile('bmp',true);
            {$ELSE}
            URL := TIWServerControllerBase.NewCacheFile('bmp');
            {$ENDIF}
            BMP.SaveToFile(URL);
            URL := FCacheDir + ExtractFileName(URL);
            BMP.Free;
          end;
        end;

        Name := arMenuName[Idx] + '_' + IntToStr(i);

//      OutputDebugString(pchar('item: ' + SubItem.Caption + ' * ' + BoolToStr(SubItem.Visible) + ' * ' + Name));

        ItemSP := IntToStr(FItemSpacing);

      (*
      {$IFDEF TMSIW6}
      if (TIWComponent40Context(AContext).WebApplication.Browser = brMozilla) then
      {$ELSE}
      if (WebApplication.Browser = brMozilla) then
      {$ENDIF}
        ItemSP := '0';
      *)

        IconColorTo := '';

        if (FIconBackgroundColorTo <> clNone) then
          IconColorTo := HTMLClr(FIconBackgroundColorTo);

        if (SubItem.Caption = '-') then
        begin
          MenuCode := MenuCode
            + 'menuSpacer(''' + HTMLClr(FSeparatorColor) + ''',''' + CleanedID + '_' + Name + ''','''
            + IIF(FShowIcons,'True','False') + ''',''' + IntToStr(FOpacity) + ''',''' + ItemSP
            + ''',''' + HTMLClr(FItemColor) + ''',''' + HTMLClr(FIconBackgroundColor)
            + ''',''' + IconColorTo + ''');'#13;
        end
        else
        begin
          if (FClientEvents.IndexOf(SubItem.Name) >= 0) then
          begin
            MenuCode := MenuCode
              + 'function ' + CleanedID + '_' + Name + '(el)  {'#13
              + '  hideAllMenus();'#13
              + '  ' + FClientEvents.Items[FClientEvents.IndexOf(SubItem.Name)].FItemScript + #13
              + '  ' + CleanedID + 'SubmitValue(''' + CleanedID + '_' + Name + ''')'#13
              + '}'#13;
          end;

          Cap := SubItem.Caption;
          Cap := StringReplace(Cap, '''', '&#39;', [rfReplaceAll, rfIgnoreCase]);
          Cap := StringReplace(Cap, '<', '&lt;', [rfReplaceAll, rfIgnoreCase]);
          Cap := StringReplace(Cap, '>', '&gt;', [rfReplaceAll, rfIgnoreCase]);

          if (SubItem.Count = 0) then
            MenuCode := MenuCode
              + 'menuItem(''' + Cap + ''',''' + Name + ''','
              + IntToStr(Level) + ',''' + CleanedID + '_' + Name + ''',''' + URL + ''', '''
              + IIF(FShowIcons,'True','False') + ''',''' + HTMLClr(FIconBackgroundColor) + ''',''' + IntToStr(FItemHeight)
              + ''',''' + IntToStr(FOpacity) + ''',''' + IIF(UseImage,'True','False') + ''',''' + ItemSP
              + ''',''' + IIF((FClientEvents.IndexOf(SubItem.Name) >= 0),'True','False') + ''',''' + IIF(SubItem.Enabled,'True','False')
              + ''',''' + IIF(SubItem.Checked, 'True', 'False') + ''',''' + IconColorTo + ''');'#13
          else
          begin
            AutoNumber := AutoNumber + 1;
            MenuCode := MenuCode
              + 'subMenuLabel(''' + Cap + ''', ' + IntToStr(AutoNumber) + ',''' + Name + ''','
              + IntToStr(Level) + ', ''' + TextAlignToStr(TextAlignment) + ''','''
              + CleanedID + '_' + Name + ''',''' + URL + ''',''' + IIF(FShowIcons, 'True', 'False') + ''','''
              + HTMLClr(FIconBackgroundColor) + ''',''' + IntToStr(FItemHeight) + ''','''
              + IntToStr(Opacity) + ''',''' + IIF(UseImage, 'True', 'False') + ''',''' + ItemSP
              + ''',''' + IIF(SubItem.Enabled, 'True', 'False') + ''',''' + IconColorTo + ''');'#13;

//              OutputDebugString(pchar('AutoNumber: ' + IntToStr(AutoNumber) + ' **NAME: ' + Name));
            ID[i-1] := AutoNumber;
            arMenuId.Add(IntToStr(AutoNumber));
            arMenuName.Add(Name);
          end;
        end;
      end;
    end;

    MenuCode := MenuCode
      + 'endMenu();'#13
      + 'changeObjectVisibility(''' + CleanedID + '_' + arMenuName[idx] + ''',''hidden'');'#13;

    for i := 1 to AItem.Count do
    begin
      SubItem := AItem.Items[i-1];

      if (SubItem.Visible) then
      begin
        if (SubItem.Count > 0) then
        begin
          Level := Level + 1;
          MakeMenu(IntToStr(ID[i-1]),SubItem);
        end;
      end;
    end;

    Level := Level - 1;

  end;
  Result := MenuCode;
end;

procedure TTIWMainMenu.CacheDir;
begin
  FCacheDir := GetCacheDir(Self);
end;

{$IFDEF TMSIW6}
function TTIWMainMenu.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
{$ELSE}
function TTIWMainMenu.RenderHTML: TIWHTMLTag;
{$ENDIF}
var
  FImgName, GradientDir, StyleMenu, StyleChecked, BdrWidth : string;
  r, r2, g, g2, b, b2 : integer;
  NewRed, NewRed2, NewGreen, NewGreen2, NewBlue, NewBlue2 : integer;
  Hovercolor3, HoverColor4 : TIWColor;
  weight, CleanedID, Css, JavaScript, OpenMenu : string;
  ColorValue, ColorValue2, NewColor, NewColor2 : integer;
  IconColorTo, URL, Cap, JSSubMenu, TiersArray, checkNumberOfMenus : string;
  AItem : TMenuItem;
  i, k : integer;
  BMP : TBitmap;
  Parent, Scrpt, Tag : TIWHTMLTag;
  isPartial: Boolean;
  submitclick, ajaxcall: string;

begin
  CacheDir;

  {$IFDEF TMSIW6}
  with AContext.PageContext as TIWPageContext40 do
    isPartial := WebApplication.IsPartialUpdate;
  {$ELSE}
  isPartial := false;
  {$ENDIF}

  {$IFDEF TMSIW6}
  if not isPartial then
  begin
    TIWComponent40Context(AContext).AddScriptFile('/js/TMSMENU.js');
    TIWComponent40Context(AContext).AddScriptFile('/js/TMSMENUSETTINGS.js');
    TIWComponent40Context(AContext).AddScriptFile('/js/TMSMENUUTIL.js');
  end;
  {$ELSE}
  AddScriptFile('/js/TMSMENU.js');
  AddScriptFile('/js/TMSMENUSETTINGS.js');
  AddScriptFile('/js/TMSMENUUTIL.js');
  {$ENDIF}

  {$IFDEF TMSIW6}
  if not isPartial then
  begin
    if not (AContext.WebApplication.Browser = brIE) then
      TIWComponent40Context(AContext).AddToInitProc('document.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT | Event.CLICK);');
  end;
  {$ELSE}
  if not (WebApplication.Browser = brIE) then
    AddToInitProc('document.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT | Event.CLICK);');
  {$ENDIF}

  CleanedID := HTMLName;
  BdrWidth := '-1';

  if not FSubMenuGlyph.Empty then
  begin
    if FSubMenuGlyph.IsGIF then
    {$IFDEF TMSIW71}
      FImgName := TIWServerControllerBase.NewCacheFile('gif',true)
    {$ELSE}
      FImgName := TIWServerControllerBase.NewCacheFile('gif')
    {$ENDIF}
    else
    {$IFDEF TMSIW71}
      FImgName := TIWServerControllerBase.NewCacheFile('jpg',true);
    {$ELSE}
      FImgName := TIWServerControllerBase.NewCacheFile('jpg');
    {$ENDIF}

    FSubMenuGlyph.SaveToFile(FImgName);
    FImgName := FCacheDir + ExtractFileName(FImgName);
  end
  else
    FImgName := '';

	Css := '';

	Css := Css
    + '<style type=text/css>'#13;

  {$IFDEF TMSIW6}
  if ((FRootItemColor <> clNone) and (RootItemColorTo <> clNone) and (TIWComponent40Context(AContext).WebApplication.Browser = brIE)) then
  {$ELSE}
  if ((FRootItemColor <> clNone) and (RootItemColorTo <> clNone) and (WebApplication.Browser = brIE)) then
  {$ENDIF}
  begin
    if (FRootItemGradientDirection = gdHorizontal) then
      GradientDir := '1'
    else
      GradientDir := '0';

    StyleMenu := 'filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=' + GradientDir + ', StartColorStr=' + HTMLClr(FRootItemColor) + ',EndColorStr=' + HTMLClr(FRootItemColorTo) + ');';
  end
  else
  begin
    if (FRootItemColor <> clNone) then
      StyleMenu := '  background:' + HTMLClr(FRootItemColor)
    else
      StyleMenu := '  background:' + HTMLClr(clBtnFace);
  end;

  Css := Css
 	  + '.' + CleanedID + 'root'#13
    + '{'#13
    + '  background: ' + HTMLClr(Color) + ';'#13
    + FontToCSS(FRootItemFont,true) + #13;

  {$IFDEF TMSIW6}
  if (TIWComponent40Context(AContext).WebApplication.Browser = brIE) then
  {$ELSE}
  if (WebApplication.Browser = brIE) then
  {$ENDIF}
    Css := Css
      + '  border: ' + IntToStr(FRootItemBorderWidth) + ' solid ' + HTMLClr(FRootItemBorderColor) + ';'#13
  else
    Css := Css
      + '  border: 1 solid ' + HTMLClr(FRootItemBorderColor) + ';'#13;

  Css := Css
    + '  padding: 1;'#13
    + '  padding-left: 7;'#13
    + '  padding-right: 7;'#13
    + '  margin:6;'#13
    + StyleMenu + ';' + #13;

  //Modified - no width
  (*
  if assigned(FMenu) then
  begin
    if (FMenu.Items.Count > 0) then
      Css := Css
        + '  width:' + IntToStr(Self.Width div FMenu.Items.Count) + ';';
  end;
  *)
  //end Modified

  Css := Css
		+ '}'#13;

  Css := Css
    + '.' + CleanedID + 'textItem'#13
    + '{'#13
    + '  ' + TextAlignToStr(FTextAlignment) + ';'#13
    + '  height: ' + IntToStr(FItemHeight) + ';'#13
    + '  ' + FontToCSS(Font,false) + ';'#13;

  Css := Css
    + '}'#13;

  if (fsBold in Font.Style) then
    Weight := 'font-weight: bold;'#13;

  Css := Css
    + '.' + CleanedID + 'disabled'#13
    + '{'#13
    + '  color:buttonshadow;'#13
    + '  ' + TextAlignToStr(FTextAlignment) + ';'#13
    + '  font-family: ' + Font.FontName + ';'#13
    + '  font-size:' + IntToStr(Font.Size) + ';'#13
    + '  ' + Weight
    + '  valign: center;'#13
    + '}'#13;

  {$IFDEF TMSIW6}
  if ((TIWComponent40Context(AContext).WebApplication.Browser = brIE) and (FHoverColorTo <> clNone)) then
  {$ELSE}
  if ((WebApplication.Browser = brIE) and (FHoverColorTo <> clNone)) then
  {$ENDIF}
    StyleChecked := 'filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=1, StartColorStr=' + HTMLClr(FHoverColor) + ',EndColorStr=' + HTMLClr(FHoverColorTo) + ')'
  else
    StyleChecked := 'background:' + HTMLClr(FHoverColor);

  Css := Css
    + '.' + CleanedID + 'checked'#13
    + '{'#13
    + '  ' + StyleChecked + ';'#13
    + '  border:1 solid darkblue;'#13
    + '  font-family: webdings;'#13
    + '  width: 20;'#13
    + '  text-align: center;'#13
    + '  valign: center;'#13
    + '}'#13;

  Css := Css
    + '.' + CleanedID + 'more'#13
    + '{'#13
    + '  color:' + HTMLClr(Font.Color) + ';'#13
    + '}'#13;

 	Css := Css
	  + '</style>'#13;

	JavaScript := '';

  if Assigned (FMenu) then
  begin

  if (FMenu.Items.Count > 0) then
  begin
    JavaScript := '<SCRIPT>'#13;

    JavaScript := JavaScript
      + 'var ' + CleanedID + 'array = new Array();'#13
			+ CleanedID + 'array[0] = "' + HTMLClr(FHoverColor) + '";'#13;

//		if (FHoverColorTo = clNone) then
    {$IFDEF TMSIW6}
    if ((TIWComponent40Context(AContext).WebApplication.Browser <> brIE) or (FHoverColorTo = clNone)) then
    {$ELSE}
    if ((WebApplication.Browser <> brIE) or (FHoverColorTo = clNone)) then
    {$ENDIF}
		  JavaScript := JavaScript
        + CleanedID + 'array[1] = "null";'#13
  	else
			JavaScript := JavaScript
			  + CleanedID + 'array[1] = "' + HTMLClr(FHoverColorTo) + '"'#13;

		JavaScript := JavaScript
		  + CleanedID + 'array[2] = "' + HTMLClr(FItemColor) + '";'#13
      + CleanedID + 'array[3] = "' + HTMLClr(FRootItemColor) + '";'#13
  		+ CleanedID + 'array[4] = "' + HTMLClrEx(FRootItemColorTo) + '";'#13
			+ CleanedID + 'array[5] = "' + HTMLClr(FRootItemBorderColor) + '";'#13;

		OpenMenu := '1';

		if (FOpen = moClick) then
			OpenMenu := '0';

		JavaScript := JavaScript
		  + CleanedID + 'array[6] = "' + OpenMenu + '";'#13
      + CleanedID + 'array[7] = "' + HTMLClr(FIconBackgroundColor) + '";'#13;

  	if (FHoverColorTo <> clNone) then
    begin
			if (FHoverGradientDirection = gdVertical) then
      begin
			  JavaScript := JavaScript
				  + CleanedID + 'array[8] = "none";'#13
					+ CleanedID + 'array[9] = "none";'#13
					+ CleanedID + 'array[10] = "' + GradDirToStr(FHoverGradientDirection) + '";'#13;
      end
			else
      begin
        ColorValue := ColorToRGB(FHoverColor);
        r := (ColorValue AND $FF);
        g := (ColorValue AND $FF00) shr 8;
        b := (ColorValue AND $FF0000) shr 16;
        ColorValue2 := ColorToRGB(HoverColorTo);
        r2 := (ColorValue2 AND $FF);
        g2 := (ColorValue2 AND $FF00) shr 8;
        b2 := (ColorValue2 AND $FF0000) shr 16;

        NewRed := Round(r * 0.9 + r2 * 0.1);
        NewGreen := Round(g * 0.9 + g2 * 0.1);
        NewBlue := Round(b * 0.9 + b2 * 0.1);
        NewColor := NewRed + (NewGreen shl 8) + (NewBlue shl 16);

        NewRed2 := Round(r * 0.1 + r2 * 0.9);
        NewGreen2 := Round(g * 0.1 + g2 * 0.9);
        NewBlue2 := Round(b * 0.1 + b2 * 0.9);
        NewColor2 := NewRed2 + (NewGreen2 shl 8) + (NewBlue2 shl 16);

        HoverColor3 := StringToColor(IntToStr(NewColor));
        HoverColor4 := StringToColor(IntToStr(NewColor2));

				JavaScript := JavaScript
				  + CleanedID + 'array[8] = "' + HTMLClr(HoverColor3) + '";'#13
					+ CleanedID + 'array[9] = "' + HTMLClr(HoverColor4) + '";'#13
					+ CleanedID + 'array[10] = "' + GradDirToStr(FHoverGradientDirection) + '";'#13;
      end;
    end
		else
    begin
		  JavaScript := JavaScript
			  + CleanedID + 'array[8] = "none";'#13
				+ CleanedID + 'array[9] = "none";'#13
				+ CleanedID + 'array[10] = "none";'#13;
    end;

    if (FAutoHiding) then
      JavaScript := JavaScript
        + CleanedID + 'array[11] = "true";'#13
    else
      JavaScript := JavaScript
        + CleanedID + 'array[11] = "false";'#13;

    {$IFDEF TMSIW6}
    if ((TIWComponent40Context(AContext).WebApplication.Browser <> brIE) or not(FBackgroundImage.Empty) or not (FUseBorder) or (FHoverColorTo <> clNone)) then
    {$ELSE}
    if ((WebApplication.Browser <> brIE) or (FHoverColorTo <> clNone) or not(FBackgroundImage.Empty) or not (FUseBorder)) then
    {$ENDIF}
      BdrWidth := '0';

    JavaScript := JavaScript
      + CleanedID + 'array[12] = "' + HTMLClr(FHoverFontColor) + '";'#13
      + CleanedID + 'array[13] = "' + HTMLClr(Font.Color) + '";'#13
      + CleanedID + 'array[14] = "' + BdrWidth + '";'#13
      + CleanedID + 'array[15] = "' + HTMLClr(FHoverBorderColor) + '";'#13;

    {$IFDEF TMSIW6}
    if (TIWComponent40Context(AContext).WebApplication.Browser = brIE) then
    {$ELSE}
    if (WebApplication.Browser = brIE) then
    {$ENDIF}
      JavaScript := JavaScript
        + CleanedID + 'array[16] = "' + IntToStr(FRootItemBorderWidth) + '";'#13
    else
      JavaScript := JavaScript
        + CleanedID + 'array[16] = "1";'#13;

    JavaScript := JavaScript
      + CleanedID + 'array[17] = "' + HTMLClr(FRootItemHoverFontColor) + '";'#13
      + CleanedID + 'array[18] = "' + HTMLClr(FRootItemFont.Color) + '";'#13
      + CleanedID + 'array[19] = "' + IntToStr(FOpacity) + '";'#13;

    {$IFDEF TMSIW6}
    if (TIWComponent40Context(AContext).WebApplication.Browser = brIE) then
    {$ELSE}
    if (WebApplication.Browser = brIE) then
    {$ENDIF}
      JavaScript := JavaScript
        + CleanedID + 'array[20] = "' + FadeToStr(Fade) + '";'#13
    else
      JavaScript := JavaScript
        + CleanedID + 'array[20] = "0";'#13;

    JavaScript := JavaScript
      + CleanedID + 'array[21] = "' + IIF(FShowIcons,'True','False') + '";'#13
      + CleanedID + 'array[22] = "' + IntToStr(ItemSpacing) + '";'#13;

    if not (FBackgroundImage.Empty) then
      JavaScript := JavaScript
        + CleanedID + 'array[23] = "True";'#13
    else
      JavaScript := JavaScript
        + CleanedID + 'array[23] = "False";'#13;

    IconColorTo := '';

    if (FIconBackgroundColorTo <> clNone) then
      IconColorTo := HTMLClr(FIconBackgroundColorTo);

    JavaScript := JavaScript
      + CleanedID + 'array[24] = "' + IconColorTo + '";'#13;

    JavaScript := JavaScript
      + CleanedID + 'array[25] = "' + HTMLClrEx(FRootItemHoverColor) + '";'#13
      + CleanedID + 'array[26] = "' + HTMLClrEx(FRootItemHoverColorTo) + '";'#13
      + CleanedID + 'array[27] = "' + HTMLClrEx(FRootItemBorderHoverColor) + '";'#13;

    if (FRootItemDownColor = clNone) then
    begin
      JavaScript := JavaScript
        + CleanedID + 'array[28] = "' + HTMLClrEx(FRootItemHoverColor) + '";'#13
        + CleanedID + 'array[29] = "' + HTMLClrEx(FRootItemHoverColorTo) + '";'#13;
    end
    else
    begin
      JavaScript := JavaScript
        + CleanedID + 'array[28] = "' + HTMLClrEx(FRootItemDownColor) + '";'#13
        + CleanedID + 'array[29] = "' + HTMLClrEx(FRootItemDownColorTo) + '";'#13;
    end;

    JavaScript := JavaScript
      + CleanedID + 'array[30] = "' + IIF((FRootItemGradientDirection = gdHorizontal),'1','0') + '";'#13
      + CleanedID + 'array[31] = "True";'#13
	    + 'getBrowser();'#13
		  + 'setProperties(' + CleanedID + 'array,''' + CleanedID + ''');'#13
//      + 'startMenuBar(' + IntToStr(Width) + ',''' + CleanedID + 'arProp'',''' + CleanedID + 'array'',''' + FImgName + ''');'#13;
      + 'startMenuBar(''' + CleanedID + 'arProp'',''' + CleanedID + 'array'',''' + FImgName + ''');'#13;

    for i := 1 to FMenu.Items.Count do
		begin
		  AItem := FMenu.Items[i-1];

      if (AItem.Visible) then
      begin

        arMenuId.Add(IntToStr(i));
        arMenuName.Add(IntToStr(i));
        URL := '';

        if (AItem.ImageIndex >= 0) and Assigned(FMenu.Images) and not (AItem.Checked) then
        begin
          if (FMenu.Images.Count > AItem.ImageIndex) then
          begin
            BMP := TBitmap.Create;
            FMenu.Images.BkColor := FIconBackgroundColor;
            FMenu.Images.GetBitmap(AItem.ImageIndex,BMP);
            URL := '';
            {$IFDEF TMSIW71}
            URL := TIWServerControllerBase.NewCacheFile('bmp',true);
            {$ELSE}
            URL := TIWServerControllerBase.NewCacheFile('bmp');
            {$ENDIF}
            BMP.SaveToFile(URL);
            URL := FCacheDir + ExtractFileName(URL);
            BMP.Free;
          end;
        end;

        Cap := AItem.Caption;
        Cap := StringReplace(Cap,'''','&#39;',[rfReplaceAll, rfIgnoreCase]);
        Cap := StringReplace(Cap,'<','&lt;', [rfReplaceAll, rfIgnoreCase]);
        Cap := StringReplace(Cap, '>','&gt;', [rfReplaceAll, rfIgnoreCase]);

        if (AItem.Count = 0) then
        begin
          if (FClientEvents.IndexOf(AItem.Name) >= 0) then
          begin
            JavaScript := javascript
              + 'function ' + CleanedID + '_' + IntToStr(i) + '(el) {'#13
              + '  hideAllMenus();'#13
              + '  ' + FClientEvents.Items[FClientEvents.IndexOf(AItem.Name)].FItemScript + #13
              + '  ' + CleanedID + 'SubmitValue(''' + CleanedID + '_'  + IntToStr(i) + ''')'#13
              + '}'#13;
          end;

          JavaScript := JavaScript
            + 'menuLabelBlank(''' + Cap + ''',' + IntToStr(i) + ',' + IntToStr(Width div FMenu.Items.Count)
            + ',''' + TextAlignToStr(TextAlignment) + ''',''' + CleanedID + '_' + IntToStr(i) + ''',''' + IntToStr(Height)
            + ''',''' + CleanedID + 'array'',''' + IIF((FClientEvents.IndexOf(AItem.Name) >= 0),'True','False') + ''',''' + URL + ''');'#13;
        end
        else
        begin
          if (FClientEvents.IndexOf(AItem.Name) >= 0) then
          begin
            JavaScript := javascript
              + 'function ' + CleanedID + '_' + IntToStr(i) + '(el) {'#13
              + '  ' + FClientEvents.Items[FClientEvents.IndexOf(AItem.Name)].FItemScript + #13
              + '  showMenu(''' + IntToStr(i) + ''',event,''' + TextAlignToStr(TextAlignment) + ''',''' + CleanedID + '_' + IntToStr(i) + ''',' + IntToStr(AItem.Count) + ');'#13
              + '}'#13;
          end;

          JavaScript := JavaScript
            + 'menuLabel(''' + Cap + ''',' + IntToStr(i) + ',' + IntToStr(Width div FMenu.Items.Count)
            + ',''' + TextAlignToStr(TextAlignment) + ''',''' + CleanedID + '_' + IntToStr(i) + ''',''' + IntToStr(Height)
            + ''',''' + CleanedID + 'array'',''' + IIF((FClientEvents.IndexOf(AItem.Name) >= 0),'True','False') + ''',''' + URL + ''',' + IntToStr(AItem.Count) + ');'#13;
        end;
      end;
		end;

    JavaScript := JavaScript
      + 'endMenuBar();'#13
      + '</SCRIPT>'#13;

	  AutoNumber := FMenu.Items.Count;

	  JSSubMenu := '';

	  for i := 1 to FMenu.Items.Count do
    begin
		  Level := 0;
      MenuCode := '';
			AItem := FMenu.Items[i-1];
      if (AItem.Visible) then
      begin
  			JSSubMenu := JSSubMenu
			    + MakeMenu(IntToStr(i), AItem);
      end;
    end;

    submitclick := ' return SubmitClick('#39+HTMLName+#39+',name,' + #39 + 'false' + #39 + ');'#13;

    {$IFDEF TMSIW9}
    if Assigned(FOnAsyncMenuClick) then
    begin
      ajaxcall := 'processAjaxEvent(''onMenuClick'', '
        + HTMLControlImplementation.IWCLName
        + ',''' + HTMLName + '.' + 'DoAsyncMenuClick' + ''','
        + 'true' + ', null, '
        + 'true' + ');';

        Acontext.WebApplication.RegisterCallBack(HTMLName+'.DoAsyncMenuClick', DoAsyncMenuClick);

        submitclick := '';
    end;
   {$ENDIF}

		JSSubMenu := JSSubMenu
		  + 'function ' + CleanedID + 'SubmitValue(name)'#13
			+ '{'#13
      + 'document.getElementById("'+HTMLName+'_INPUT").value = name;'#13
      + ajaxcall
      + submitclick
      + '}'#13;

    TiersArray := '';

    TiersArray := TiersArray
		  + '<SCRIPT>'#13
      + '  var ' + CleanedID + 'arProp = new Array();'#13;

    for k := 0 to Tiers.Count - 1 do
    begin
      if (Tiers[k] = 'null') then
			  TiersArray := TiersArray
				  + CleanedID + 'arProp[' + IntToStr(k) + '] = null;'#13
			else
				TiersArray := TiersArray
					+ CleanedID + 'arProp[' + IntToStr(k) + '] = ' + Tiers[k] + ';'#13;
    end;

		TiersArray := TiersArray
		  + '</SCRIPT>'#13;
  end;
  end;

  Tag := TIWHTMLTag.CreateTag('DIV');
  Tag.AddStringParam('class',HTMLName + 'CSS');
  Tag.AddStringParam('NAME',HTMLName);
  Tag.AddStringParam('ID',HTMLName);
  Tag.AddStringParam('STYLE', 'background-color:' + HTMLClr(Color));
  Parent := TIWHTMLTag.CreateTag('');
  Tag.Contents.AddText(Css);

  if not isPartial then
  begin
    Tag.Contents.AddText(TiersArray);

    checkNumberOfMenus := '<SCRIPT>'#13
      + '  if (parseInt(' + IntToStr(Tiers.Count) + ') > parseInt(numMenus)) '#13
      + '    numMenus = ' + IntToStr(Tiers.Count) + ';'#13
      + '</SCRIPT>'#13;

    Tag.Contents.AddText(checkNumberOfMenus);
    Tag.Contents.AddText(JavaScript);
  end;


  if not (assigned(FMenu)) or (FMenu.Items.Count = 0) then
  begin
      Tag.AddStringParam('STYLE', 'width:' + IntToStr(Self.Width) + ';background:' + HtmlClr(RootItemColor));
      Tag.Contents.AddText('&nbsp;');
  end;

  Scrpt := nil;
  if not isPartial then
  begin
    Scrpt := TIWHTMLTag.CreateTag('SCRIPT');
    Scrpt.Contents.AddText(JSSubMenu);
  end;  

  {$IFDEF TMSIW6}
  Parent.Contents.Add(Tag);
  if not isPartial then
    Parent.Contents.Add(Scrpt);
  {$ENDIF}
  {$IFNDEF TMSIW6}
  Parent.Contents.AddTagAsObject(Tag);
  Parent.Contents.AddTagAsObject(Scrpt);
  {$ENDIF}

  //clear arrays before refresh.
  //fixed: if some items are set to visible = false
  //after refresh the # of items in the array does no longer correspond to the
  //number of visible items and some subitems might not be displayed.
  arMenuId.Clear;
  arMenuName.Clear;

  Result := Parent;

  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName);
    AddStringParam('ID',HTMLName+'_INPUT');
  end;
end;

procedure TTIWMainMenu.BackgroundChanged(Sender: TObject);
begin
  Invalidate;
end;

{$IFDEF TMSIW6}
procedure TTIWMainMenu.IWPaint;
{$ELSE}
procedure TTIWMainMenu.Paint;
{$ENDIF}
var
  i: Integer;
  txt: string;
  r: TRect;
  WidthItem, SubWidth, BeginLeft : integer;
begin
  r := GetClientRect;
  if Assigned(FMenu) then
  begin
    if (FMenu.Items.Count > 0) then
      WidthItem := Self.Width div FMenu.Items.Count
    else
      WidthItem := Self.Width;

    SubWidth := WidthItem;
    BeginLeft := 0;

    Canvas.Font.Name := FRootItemFont.FontName;
    Canvas.Font.Size := FRootItemFont.Size;
    Canvas.Font.Color := FRootItemFont.Color;
    Canvas.Font.Style := FRootItemFont.Style;

    for i := 1 to FMenu.Items.Count do
    begin
      txt := FMenu.Items[i - 1].Caption;

      with Canvas do
      begin
        r.Left := BeginLeft;
        r.Top := 0;
        r.Right := SubWidth;
        r.Bottom := FItemHeight;
        Pen.Color := RootItemBorderColor;
        Pen.Width := FRootItemBorderWidth;
        if (FRootItemColorTo <> clNone) then
        begin
          if (FRootItemGradientDirection = gdVertical) then
            DrawGradient(Canvas, FRootItemColor, FRootItemColorTo, 80, r, False)
          else
            DrawGradient(Canvas,FRootItemColor, FRootItemColorTo, 80, r, True);
          Brush.Style := bsClear;
          TextOut(r.Left + ((SubWidth - BeginLeft) div 2) - TextWidth(txt) div 2, (FItemHeight) div 2 - TextHeight(txt) div 2,txt);
        end
        else
        begin
          Brush.Color := FRootItemColor;
          TextRect(r,r.Left + ((SubWidth - BeginLeft) div 2) - TextWidth(txt) div 2, (FItemHeight) div 2 - TextHeight(txt) div 2, txt);
        end;
        Brush.Style := bsClear;
      end;
      BeginLeft := BeginLeft + WidthItem;
      SubWidth := SubWidth + WidthItem;
    end;

    if (FMenu.Items.Count = 0) then
    begin
      Canvas.Brush.Color := FRootItemColor;
      Canvas.Pen.Color := FRootItemBorderColor;
      Canvas.Pen.Width := FRootItemBorderWidth;
      Canvas.Rectangle(r.Left, r.Top, r.Left + Self.Width, r.Top + FItemHeight);
    end;
  end
  else
  begin
    Canvas.Brush.Color := FRootItemColor;
    Canvas.Pen.Color := FRootItemBorderColor;
    Canvas.Pen.Width := FRootItemBorderWidth;
    Canvas.Rectangle(r.Left, r.Top, r.Left + Self.Width, r.Top + FItemHeight);
  end;
end;

procedure TTIWMainMenu.DrawGradient(Canvas: TCanvas; FromColor, ToColor: TIWColor; Steps: Integer; r:TRect; Direction: Boolean);
var
  diffr,startr,endr: Integer;
  diffg,startg,endg: Integer;
  diffb,startb,endb: Integer;
  iend: Integer;
  rstepr,rstepg,rstepb,rstepw: Real;
  i,stepw: Word;

begin
  if Steps = 0 then
    Steps := 1;

  FromColor := ColorToRGB(FromColor);
  ToColor := ColorToRGB(ToColor);

  startr := (FromColor and $0000FF);
  startg := (FromColor and $00FF00) shr 8;
  startb := (FromColor and $FF0000) shr 16;
  endr := (ToColor and $0000FF);
  endg := (ToColor and $00FF00) shr 8;
  endb := (ToColor and $FF0000) shr 16;

  diffr := endr - startr;
  diffg := endg - startg;
  diffb := endb - startb;

  rstepr := diffr / steps;
  rstepg := diffg / steps;
  rstepb := diffb / steps;

  if Direction then
    rstepw := (R.Right - R.Left) / Steps
  else
    rstepw := (R.Bottom - R.Top) / Steps;

  with Canvas do
  begin
    for i := 0 to Steps - 1 do
    begin
      endr := startr + Round(rstepr*i);
      endg := startg + Round(rstepg*i);
      endb := startb + Round(rstepb*i);
      stepw := Round(i*rstepw);
      Pen.Color := endr + (endg shl 8) + (endb shl 16);
      Brush.Color := Pen.Color;
      if Direction then
      begin
        iend := R.Left + stepw + Trunc(rstepw) + 1;
        if iend > R.Right then
          iend := R.Right;
        Rectangle(R.Left + stepw,R.Top,iend,R.Bottom)
      end
      else
      begin
        iend := R.Top + stepw + Trunc(rstepw)+1;
        if iend > r.Bottom then
          iend := r.Bottom;
        Rectangle(R.Left, R.Top+stepw,R.Right,iend);
      end;
    end;
  end;
end;

procedure TTIWMainMenu.SetValue(const value:string);
begin
  FSelectedItem := value;
end;

procedure TTIWMainMenu.Submit(const AValue: string);
var
  Menu: TMenuItem;
begin
  Menu := StringToMenuItem(AValue);

  if Assigned(Menu) then
  begin
    {$IFDEF DELPHI6_LVL}
    if Menu.AutoCheck then
      Menu.Checked := not Menu.Checked;
    {$ENDIF}
    if Assigned(Menu.OnClick) then
       Menu.OnClick(Menu);
  end;
end;


procedure TTIWMainMenu.SetAutoHiding(const Value : Boolean);
begin
  FAutoHiding := Value;
end;

procedure TTIWMainMenu.SetBackgroundImage(const Value: TIPicture);
begin
  FBackgroundImage.Assign(Value);
  Invalidate;
end;

{$IFNDEF TMSIW71}
procedure TTIWMainMenu.SetDesignMode(const Value: Boolean);
begin
  FDesignMode := Value;
  Invalidate;
end;
{$ENDIF}

procedure TTIWMainMenu.SetFade(const Value : TTIWFade);
begin
  FFade := Value;
end;

procedure TTIWMainMenu.SetHoverGradientDirection(const Value : TTIWGradientDirection);
begin
  FHoverGradientDirection := Value;
end;

procedure TTIWMainMenu.SetIconBackgroundColor(const Value : TIWColor);
begin
  FIconBackgroundColor := Value;
end;

procedure TTIWMainMenu.SetIconBackgroundColorTo(const Value : TIWColor);
begin
  FIconBackgroundColorTo := Value;
end;

procedure TTIWMainMenu.SetItemColor(const Value: TIWColor);
begin
  FItemColor := Value;
end;

procedure TTIWMainMenu.SetItemHeight(const Value : Integer);
begin
  FItemHeight := Value;
end;

procedure TTIWMainMenu.SetMenu(const Value: TMenu);
begin
  FMenu := Value;
  Invalidate;
end;

procedure TTIWMainMenu.SetOpacity(const Value : Integer);
begin
  if (Value < 0) or (Value > 100) then
    raise Exception.Create('Value required between 0 and 100')
  else
  FOpacity := Value;
end;

procedure TTIWMainMenu.SetRootItemBorderColor(const Value : TIWColor);
begin
  FRootItemBorderColor := Value;
end;

procedure TTIWMainMenu.SetRootItemBorderHoverColor(const Value : TIWColor);
begin
  FRootItemBorderHoverColor := Value;
end;

procedure TTIWMainMenu.SetRootItemBorderWidth(const Value : integer);
begin
  FRootItemBorderWidth := Value;
end;

procedure TTIWMainMenu.SetRootItemColor(const Value: TIWColor);
begin
  FRootItemColor := Value;
end;

procedure TTIWMainMenu.SetRootItemColorTo(const Value: TIWColor);
begin
  FRootItemColorTo := Value;
end;

procedure TTIWMainMenu.SetRootItemHoverColor(const Value : TIWColor);
begin
  FRootItemHoverColor := Value;
end;

procedure TTIWMainMenu.SetRootItemHoverColorTo(const Value : TIWColor);
begin
  FRootItemHoverColorTo := value;
end;

procedure TTIWMainMenu.SetRootItemDownColor(const Value : TIWColor);
begin
  FRootItemDownColor := Value;
end;

procedure TTIWMainMenu.SetRootItemHoverFontColor(const Value : TIWColor);
begin
  FRootItemHoverFontColor := Value;
end;

procedure TTIWMainMenu.SetRootItemDownColorTo(const Value : TIWColor);
begin
  FRootItemDownColorTo := Value;
end;

procedure TTIWMainMenu.SetRootItemFont(const Value: TIWFont);
begin
  FRootItemFont.Assign(Value);
end;

procedure TTIWMainMenu.SetRootItemGradientDirection(const Value : TTIWGradientDirection);
begin
  FRootItemGradientDirection := Value;
end;

procedure TTIWMainMenu.SetSeparatorColor(const Value : TIWColor);
begin
  FSeparatorColor := Value;
end;

procedure TTIWMainMenu.SetSubMenuGlyph(const value: TIPicture);
begin
  FSubMenuGlyph.Assign(Value);
end;

procedure TTIWMainMenu.SetTextAlignment(const Value : TAlignment);
begin
  FTextAlignment := Value;
end;

procedure TTIWMainMenu.SetUseBorder(const Value : Boolean);
begin
  FUseBorder := Value;
end;

{ TTIWSideMenu }
function TTIWSideMenu.StringToMenuItem(Value: string): TMenuItem;
var
  Decode, Sub: string;
  i,err: Integer;
  Menu: TMenuItem;
begin
  Menu := nil;

  Decode := Value;
  Delete(decode,1,length(HTMLName));

  if Assigned(FMenu) then
  begin
    Menu := nil;
    while length(decode) > 0 do
    begin
      sub := decode;
      if pos('_',sub) > 0 then
        Sub := copy(sub,1,pos('_',sub) - 1);
      val(sub,i,err);

      if (i > 0) then
      begin
        if Assigned(Menu) then
          Menu := Menu.Items[i - 1]
        else
          Menu := FMenu.Items[i - 1];
      end;

      delete(decode,1,length(sub) + 1);
    end;
  end;
  Result := Menu;
end;
{$IFDEF TMSIW9}
procedure TTIWSideMenu.DoAsyncMenuClick(AParams: TStringList);
begin
  if Assigned(OnAsyncMenuClick) then
    OnAsyncMenuClick(Self, AParams, StringToMenuItem(FSelectedItem));
end;

function TTIWSideMenu.RenderAsync(
  AContext: TIWBaseHTMLComponentContext): TIWXMLTag;
begin
  Result := TIWXMLTag.CreateTag('control');
  try
    Result.AddStringParam('id', HTMLName);
    Result.AddStringParam('type', 'TTIWSIDEMENU');
    RenderAsyncCommonProperties( AContext, Result );
  except
    FreeAndNil(Result);
  end;
end;
{$ENDIF}

constructor TTIWSideMenu.Create(AOwner: TComponent);
begin
  inherited;
  {$IFDEF TMSIW6}
  {TODO}
  {$ELSE}
  FSupportsInput := True;
  FSupportsSubmit := True;
  {$ENDIF}
  FRootItemFont := TIWFont.Create;
  FRootItemFont.Size := 12;
  FRootItemFont.FontName := 'Verdana';
  FRootItemFont.Color := clBlack;
  Font.Color := clWindowText;
  Font.Size := 11;
  Font.FontName := 'Verdana';
  FAutoHiding := true;
  FBackgroundImage := TIPicture.Create;
  FBackgroundImage.OnChange := BackgroundChanged;
  FBorder := true;
  FClientEvents := TMenuClientEvents.Create;
  FDesignMode := True;
  FFade := fdNone;
  FHoverBorderColor := clHighlight;
  FHoverColor := $F0CAA6;
  FHoverColorTo := clNone;
  FHoverFontColor := clBlack;
  FHoverGradientDirection := gdHorizontal;
  FIconBackgroundColor := clBtnFace;
  FIconBackgroundColorTo := clNone;
  FItemColor := clWhite;
  FItemHeight := 20;
  FItemSpacing := 3;
  FOpacity := 100;
  FOpen := moClick;
  FRootItemColor := clBtnFace;
  FRootItemColorTo := clNone;
  FRootItemBorderColor := clBtnFace;
  FRootItemBorderWidth := 1;
  FRootItemGradientDirection := gdHorizontal;
  FRootItemHeight := 25;
  FRootItemHoverFontColor := clBlack;
  FRootItemHoverColor := clNone;
  FRootItemHoverColorTo := clNone;
  FRootItemDownColor := clNone;
  FRootItemDownColorTo := clNone;
  FRootItemBorderHoverColor := clNone;
  FSeparatorColor := clBtnFace;
  FSubMenuGlyph := TIPicture.Create;
  FUseBorder := true;
  FShowIcons := true;
  FTextAlignment := taLeftJustify;
  Self.Height := 20;
  Self.Width := 150;
  Self.BorderColor := clBtnFace;
  Self.Color := clBtnFace;
  Zindex := 10;

  arMenuId := TStringList.Create;
  arMenuName := TStringList.Create;
  Tiers := TStringList.Create;
  MenuCode := '';
  Level := 0;
  AutoNumber := 0;
  FCacheDir := '';

  if not (csDesigning in Componentstate) then
  begin
    {$IFDEF TMSIW51}
    TIWServer.AddInternalFile('IW_JS_TMSMENU','/js/TMSMENU.js');
    TIWServer.AddInternalFile('IW_JS_TMSMENUSETTINGS','/js/TMSMENUSETTINGS.js');
    TIWServer.AddInternalFile('IW_JS_TMSMENUUTIL','/js/TMSMENUUTIL.js');
    {$ELSE}
    GIWServer.AddInternalFile('IW_JS_TMSMENU');
    GIWServer.AddInternalFile('IW_JS_TMSMENUSETTINGS');
    GIWServer.AddInternalFile('IW_JS_TMSMENUUTIL');
    {$ENDIF}
  end;
end;

destructor TTIWSideMenu.Destroy;
begin
  FClientEvents.Free;
  FSubMenuGlyph.Free;
  FBackgroundImage.Free;
  FRootItemFont.Free;
  arMenuId.Free;
  arMenuName.Free;
  Tiers.Free;
  inherited;
end;

function TTIWSideMenu.HTMLClr(color: TIWColor):string;
begin
  Result := ColorToRGBString(ColorToRGB(color));
end;

function TTIWSideMenu.HTMLClrEx(color: TIWColor):string;
begin
  if (color = clNone) then
    Result := ''
  else
    Result := ColorToRGBString(ColorToRGB(color));
end;

{$IFDEF TMSIW51}
function TTIWSideMenu.CursorToHtml(Cursor : TIWCursor):string;
{$ELSE}
function TTIWSideMenu.CursorToHtml(Cursor : TCursor):string;
{$ENDIF}
begin
  case Cursor of
    {$IFDEF TMSIW51}
    crCrossHair: Result := 'crosshair';
    crDefault: Result := 'default';
    crWait: Result := 'wait';
    crAuto: Result := 'auto';
    crPointer: Result := 'pointer';
    crMove: Result := 'move';
    crEResize: Result := 'e-resize';
    crNEResize: Result := 'ne-resize';
    crNWResize: Result := 'nw-resize';
    crNResize: Result := 'n-resize';
    crSEResize: Result := 'se-resize';
    crSWResize: Result := 'sw-resize';
    crSResize: Result := 's-resize';
    crWResize: Result := 'w-resize';
    crText: Result := 'text';
    crHelp: Result := 'help';
    {$ELSE}
    crAppStart : Result := 'wait';
    crCross : Result := 'crosshair';
    crDefault : Result := 'default';
    crHandPoint : Result := 'pointer';
    crHelp : Result := 'help';
    crHourGlass : Result := 'wait';
    criBeam : Result := 'auto';
    crSizeAll : Result := 'move';
    crSizeNESW : Result := 'ne-resize';
    crSizeNS : Result := 'n-resize';
    crSizeNWSE : Result := 'nw-resize';
    crSizeWE : Result := 'e-resize';
    {$ENDIF}
  else
    Result := 'default';
  end;
end;

function TTIWSideMenu.GradDirToStr(GradDir : TTIWGradientDirection) : string;
begin
  if GradDir = gdHorizontal then
    Result := '1'
  else
    Result := '0';
end;

function TTIWSideMenu.FadeToStr(FadeSpeed : TTIWFade) : string;
begin
  case FadeSpeed of
    fdNone : Result := '0';
    fdSlow : Result := '10';
    fdMedium : Result := '7';
    fdFast : Result := '4';
  else
    Result := '0';
  end;
end;

function TTIWSideMenu.FontToCSS(AFont : TIWFont; FromRoot : Boolean) : string;
var
  Weight, Res : string;
begin
  Weight := '';
  Res := '';

  if fsBold in AFont.Style then
    Weight := #13'font-weight: bold;'#13;

  if (FromRoot) then
  begin
    if (AFont.FontName <> '') then
      Res := Res
        + '  font-family:' + AFont.FontName + ';'#13;

    if (fsItalic in AFont.Style) then
      Res := Res
        + ' font-style:italic;'#13;

    Res := Res
      + '  color:' + HTMLClr(FRootItemFont.Color) + ';'#13
      + Weight
      + '  font-size:' + IntToStr(AFont.Size) + ';'#13;
  end
  else
  begin
    if (AFont.FontName <> '') then
      Res := '  font-family:' + AFont.FontName + ';'#13;

    if (AFont.Color <> clNone) then
      Res := Res
        + '  color:' + HTMLClr(AFont.Color) + ';'#13
    else
      Res := Res
        + '  color:black;'#13;

    if (fsItalic in AFont.Style) then
      Res := Res
        + ' font-style:italic;'#13;

    Res := Res
      + Weight
      + '  font-size:' + IntToStr(AFont.Size) + ';'#13;
  end;
  Result := Res;
end;

function TTIWSideMenu.TextAlignToStr(Alignment : TAlignment) : string;
begin
  case Alignment of
    taLeftJustify:
      Result := 'text-align:left;';
    taCenter:
      Result := 'text-align:center;';
    taRightJustify:
      Result := 'text-align:right;';
    else
      Result := 'text-align:left;';
  end;
end;

function TTIWSideMenu.MakeMenu(AName : string; AItem : TMenuItem) : string;
var
  i, l, x, Idx : integer;
  Name, CleanedID, URLBack, URL, ItemSP, IconColorTo, Cap : string;
  ID : array of integer;
  UseImage : boolean;
  SubItem : TMenuItem;
  BMP : TBitmap;
begin
  //ID = new int[AItem.SubMenu.Count];
  SetLength(ID,AItem.Count);

  CleanedID := HTMLName;

  if (AItem.Count > 0) then
  begin
    if (Tiers.Count = 0) then
    begin
      for l := 0 to StrToInt(AName)- 1 do
        Tiers.Add('null');

      Tiers.Add(IntToStr(Level));
    end
    else
    begin
      if (StrToInt(AName) > Tiers.Count) then
      begin
        for x := Tiers.Count to StrToInt(AName) - 1 do
          Tiers.Add('null');

        Tiers.Add(IntToStr(Level));
      end
      else
      begin
        if (StrToInt(AName) = Tiers.Count) then
          Tiers.Add(IntToStr(Level))
        else
          Tiers[StrToInt(AName)] := IntToStr(Level);
      end;
    end;

    Idx := arMenuId.IndexOf(AName);
    URLBack := '';
    useImage := false;

    if not (FBackgroundImage.Empty) then
    begin
      UseImage := true;

      if FBackgroundImage.IsGIF then
      {$IFDEF TMSIW71}
      URLBack := TIWServerControllerBase.NewCacheFile('gif',true)
      {$ELSE}
      URLBack := TIWServerControllerBase.NewCacheFile('gif')
      {$ENDIF}
      else
      {$IFDEF TMSIW71}
      URLBack := TIWServerControllerBase.NewCacheFile('jpg',true);
      {$ELSE}
      URLBack := TIWServerControllerBase.NewCacheFile('jpg');
      {$ENDIF}

      FBackgroundImage.SaveToFile(URLBack);
      URLBack := FCacheDir + ExtractFileName(URLBack);
    end;

    MenuCode := MenuCode
      + #13
      + 'startMenu(' + AName + ',150,' + IntToStr(Level) + ',''' + HTMLClr(FBorderColor) + ''','''
      + CleanedID + '_' + arMenuName[Idx] + ''',''' + IntToStr(100+ZIndex) + ''','''
      + URLBack + ''',''' + IntToStr(Opacity) + ''');'#13;

    for i := 1 to AItem.Count do
    begin
      SubItem := AItem.Items[i-1];
      URL := '';

      if (SubItem.Visible) then
      begin
        if (SubItem.ImageIndex >= 0) and Assigned(FMenu.Images) and not (SubItem.Checked) then
        begin
          if (FMenu.Images.Count > SubItem.ImageIndex) then
          begin
            BMP := TBitmap.Create;
            FMenu.Images.BkColor := FIconBackgroundColor;
            FMenu.Images.GetBitmap(SubItem.ImageIndex,BMP);
            //URL := HTMLBmp(BMP);
            URL := '';
            {$IFDEF TMSIW71}
            URL := TIWServerControllerBase.NewCacheFile('bmp',true);
            {$ELSE}
            URL := TIWServerControllerBase.NewCacheFile('bmp');
            {$ENDIF}
            BMP.SaveToFile(URL);
            URL := FCacheDir + ExtractFileName(URL);
            BMP.Free;
          end;
        end;

        Name := arMenuName[Idx] + '_' + IntToStr(i);

        ItemSP := IntToStr(FItemSpacing);

      (*
      {$IFDEF TMSIW6}
      if (TIWComponent40Context(AContext).WebApplication.Browser = brMozilla) then
      {$ELSE}
      if (WebApplication.Browser = brMozilla) then
      {$ENDIF}
        ItemSP := '0';
      *)

        IconColorTo := '';

        if (FIconBackgroundColorTo <> clNone) then
          IconColorTo := HTMLClr(FIconBackgroundColorTo);

        if (SubItem.Caption = '-') then
        begin
          MenuCode := MenuCode
            + 'menuSpacer(''' + HTMLClr(FSeparatorColor) + ''',''' + CleanedID + '_' + Name + ''','''
            + IIF(FShowIcons,'True','False') + ''',''' + IntToStr(FOpacity) + ''',''' + ItemSP
            + ''',''' + HTMLClr(FItemColor) + ''',''' + HTMLClr(FIconBackgroundColor)
            + ''',''' + IconColorTo + ''');'#13;
        end
        else
        begin
          if (FClientEvents.IndexOf(SubItem.Name) >= 0) then
          begin
            MenuCode := MenuCode
              + 'function ' + CleanedID + '_' + Name + '(el)  {'#13
              + '  hideAllMenus();'#13
              + '  ' + FClientEvents.Items[FClientEvents.IndexOf(SubItem.Name)].FItemScript + #13
              + '  ' + CleanedID + 'SubmitValue(''' + CleanedID + '_' + Name + ''')'#13
              + '}'#13;
          end;

          Cap := SubItem.Caption;
          Cap := StringReplace(Cap, '''', '&#39;', [rfReplaceAll, rfIgnoreCase]);
          Cap := StringReplace(Cap, '<', '&lt;', [rfReplaceAll, rfIgnoreCase]);
          Cap := StringReplace(Cap, '>', '&gt;', [rfReplaceAll, rfIgnoreCase]);

          if (SubItem.Count = 0) then
            MenuCode := MenuCode
              //check ' char for caption
              + 'menuItem(''' + Cap + ''',''' + Name + ''','
              + IntToStr(Level) + ',''' + CleanedID + '_' + Name + ''',''' + URL + ''', '''
              + IIF(FShowIcons,'True','False') + ''',''' + HTMLClr(FIconBackgroundColor) + ''',''' + IntToStr(FItemHeight)
              + ''',''' + IntToStr(FOpacity) + ''',''' + IIF(UseImage,'True','False') + ''',''' + ItemSP
              + ''',''' + IIF((FClientEvents.IndexOf(SubItem.Name) >= 0),'True','False') + ''',''' + IIF(SubItem.Enabled,'True','False')
              + ''',''' + IIF(SubItem.Checked, 'True', 'False') + ''',''' + IconColorTo + ''');'#13
          else
          begin
            AutoNumber := AutoNumber + 1;
            MenuCode := MenuCode
              + 'subMenuLabel(''' + Cap + ''', ' + IntToStr(AutoNumber) + ',''' + Name + ''','
              + IntToStr(Level) + ', ''' + TextAlignToStr(TextAlignment) + ''','''
              + CleanedID + '_' + Name + ''',''' + URL + ''',''' + IIF(FShowIcons, 'True', 'False') + ''','''
              + HTMLClr(FIconBackgroundColor) + ''',''' + IntToStr(FItemHeight) + ''','''
              + IntToStr(Opacity) + ''',''' + IIF(UseImage, 'True', 'False') + ''',''' + ItemSP
              + ''',''' + IIF(SubItem.Enabled, 'True', 'False') + ''',''' + IconColorTo + ''');'#13;

            ID[i-1] := AutoNumber;
            arMenuId.Add(IntToStr(AutoNumber));
            arMenuName.Add(Name);
          end;
        end;
      end;
    end;

    MenuCode := MenuCode
      + 'endMenu();'#13
      + 'changeObjectVisibility(''' + CleanedID + '_' + arMenuName[idx] + ''',''hidden'');'#13;

    for i := 1 to AItem.Count do
    begin
      SubItem := AItem.Items[i-1];

      if (SubItem.Visible) then
      begin
        if (SubItem.Count > 0) then
        begin
          Level := Level + 1;
          MakeMenu(IntToStr(ID[i-1]),SubItem);
        end;
      end;
    end;
    Level := Level - 1;
  end;
  Result := MenuCode;
end;

procedure TTIWSideMenu.CacheDir;
begin
  FCacheDir := GetCacheDir(Self);
end;

{$IFDEF TMSIW6}
function TTIWSideMenu.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
{$ELSE}
function TTIWSideMenu.RenderHTML: TIWHTMLTag;
{$ENDIF}
var
  FImgName, GradientDir, StyleMenu, StyleChecked, BdrWidth : string;
  r, r2, g, g2, b, b2 : integer;
  NewRed, NewRed2, NewGreen, NewGreen2, NewBlue, NewBlue2 : integer;
  Hovercolor3, HoverColor4 : TIWColor;
  weight, CleanedID, Css, JavaScript, OpenMenu : string;
  ColorValue, ColorValue2, NewColor, NewColor2 : integer;
  IconColorTo, URL, Cap, JSSubMenu, TiersArray, checkNumberOfMenus : string;
  AItem : TMenuItem;
  i, k : integer;
  BMP : TBitmap;
  Parent, Scrpt, Tag : TIWHTMLTag;
  isPartial: boolean;
  submitclick, ajaxcall: string;
  
begin
  CacheDir;

  {$IFDEF TMSIW6}
  with AContext.PageContext as TIWPageContext40 do
    isPartial := WebApplication.IsPartialUpdate;
  {$ELSE}
  isPartial := false;
  {$ENDIF}

  {$IFDEF TMSIW6}
  if not isPartial then
  begin
    TIWComponent40Context(AContext).AddScriptFile('/js/TMSMENU.js');
    TIWComponent40Context(AContext).AddScriptFile('/js/TMSMENUSETTINGS.js');
    TIWComponent40Context(AContext).AddScriptFile('/js/TMSMENUUTIL.js');
  end;  
  {$ELSE}
  AddScriptFile('/js/TMSMENU.js');
  AddScriptFile('/js/TMSMENUSETTINGS.js');
  AddScriptFile('/js/TMSMENUUTIL.js');
  {$ENDIF}

  {$IFDEF TMSIW6}
  if not isPartial then
  begin
    if not (AContext.WebApplication.Browser = brIE) then
      TIWComponent40Context(AContext).AddToInitProc('document.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT | Event.CLICK);');
  end;    
  {$ELSE}
  if not (WebApplication.Browser = brIE) then
    AddToInitProc('document.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT | Event.CLICK);');
  {$ENDIF}

  CleanedID := HTMLName;
  BdrWidth := '-1';

  if not FSubMenuGlyph.Empty then
  begin
    if FSubMenuGlyph.IsGIF then
    {$IFDEF TMSIW71}
      FImgName := TIWServerControllerBase.NewCacheFile('gif',true)
    {$ELSE}
      FImgName := TIWServerControllerBase.NewCacheFile('gif')
    {$ENDIF}
    else
    {$IFDEF TMSIW71}
      FImgName := TIWServerControllerBase.NewCacheFile('jpg',true);
    {$ELSE}
      FImgName := TIWServerControllerBase.NewCacheFile('jpg');
    {$ENDIF}

    FSubMenuGlyph.SaveToFile(FImgName);
    FImgName := FCacheDir + ExtractFileName(FImgName);
  end
  else
    FImgName := '';

	Css := '';

	Css := Css
    + '<style type=text/css>'#13;

  {$IFDEF TMSIW6}
  if ((FRootItemColor <> clNone) and (RootItemColorTo <> clNone) and (TIWComponent40Context(AContext).WebApplication.Browser = brIE)) then
  {$ELSE}
  if ((FRootItemColor <> clNone) and (RootItemColorTo <> clNone) and (WebApplication.Browser = brIE)) then
  {$ENDIF}
  begin
    if (FRootItemGradientDirection = gdHorizontal) then
      GradientDir := '1'
    else
      GradientDir := '0';

    StyleMenu := 'filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=' + GradientDir + ', StartColorStr=' + HTMLClr(FRootItemColor) + ',EndColorStr=' + HTMLClr(FRootItemColorTo) + ');';
  end
  else
  begin
    if (FRootItemColor <> clNone) then
      StyleMenu := '  background:' + HTMLClr(FRootItemColor)
    else
      StyleMenu := '  background:' + HTMLClr(clBtnFace);
  end;

  Css := Css
 	  + '.' + CleanedID + 'root'#13
    + '{'#13
    + '  background: ' + HTMLClr(Color) + ';'#13
    + FontToCSS(FRootItemFont,true) + #13;

  {$IFDEF TMSIW6}
  if (TIWComponent40Context(AContext).WebApplication.Browser = brIE) then
  {$ELSE}
  if (WebApplication.Browser = brIE) then
  {$ENDIF}
    Css := Css
      + '  border: ' + IntToStr(FRootItemBorderWidth) + ' solid ' + HTMLClr(FRootItemBorderColor) + ';'#13
  else
    Css := Css
      + '  border: 1 solid ' + HTMLClr(FRootItemBorderColor) + ';'#13;

  Css := Css
    + '  padding: 1;'#13
    + '  padding-left: 7;'#13
    + '  padding-right: 7;'#13
    + '  margin:6;'#13
    + StyleMenu + #13
		+ '}'#13;

  Css := Css
    + '.' + CleanedID + 'textItem'#13
    + '{'#13
    + '  ' + TextAlignToStr(FTextAlignment) + ';'#13
    + '  height: ' + IntToStr(FItemHeight) + ';'#13
    + '  ' + FontToCSS(Font,false) + ';'#13;

  Css := Css
    + '}'#13;

  if (fsBold in Font.Style) then
    Weight := 'font-weight: bold;'#13;

  Css := Css
    + '.' + CleanedID + 'disabled'#13
    + '{'#13
    + '  color:buttonshadow;'#13
    + '  ' + TextAlignToStr(FTextAlignment) + ';'#13
    + '  font-family: ' + Font.FontName + ';'#13
    + '  font-size:' + IntToStr(Font.Size) + ';'#13
    + '  ' + Weight
    + '  valign: center;'#13
    + '}'#13;

  {$IFDEF TMSIW6}
  if ((TIWComponent40Context(AContext).WebApplication.Browser = brIE) and (FHoverColorTo <> clNone)) then
  {$ELSE}
  if ((WebApplication.Browser = brIE) and (FHoverColorTo <> clNone)) then
  {$ENDIF}
    StyleChecked := 'filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=1, StartColorStr=' + HTMLClr(FHoverColor) + ',EndColorStr=' + HTMLClr(FHoverColorTo) + ')'
  else
    StyleChecked := 'background:' + HTMLClr(FHoverColor);

  Css := Css
    + '.' + CleanedID + 'checked'#13
    + '{'#13
    + '  ' + StyleChecked + ';'#13
    + '  border:1 solid darkblue;'#13
    + '  font-family: webdings;'#13
    + '  width: 20;'#13
    + '  text-align: center;'#13
    + '  valign: center;'#13
    + '}'#13;

  Css := Css
    + '.' + CleanedID + 'more'#13
    + '{'#13
    + '  color:' + HTMLClr(Font.Color) + ';'#13
    + '}'#13;

 	Css := Css
	  + '</style>'#13;

	JavaScript := '';

  if Assigned(FMenu) then
  begin
  if (FMenu.Items.Count > 0) then
  begin
    JavaScript := '<SCRIPT>'#13;

    JavaScript := JavaScript
      + 'var ' + CleanedID + 'array = new Array();'#13
			+ CleanedID + 'array[0] = "' + HTMLClr(FHoverColor) + '";'#13;

//		if (FHoverColorTo = clNone) then
    {$IFDEF TMSIW6}
    if ((TIWComponent40Context(AContext).WebApplication.Browser <> brIE) or (FHoverColorTo = clNone)) then
    {$ELSE}
    if ((WebApplication.Browser <> brIE) or (FHoverColorTo = clNone)) then
    {$ENDIF}
		  JavaScript := JavaScript
        + CleanedID + 'array[1] = "null";'#13
  	else
			JavaScript := JavaScript
			  + CleanedID + 'array[1] = "' + HTMLClr(FHoverColorTo) + '"'#13;

		JavaScript := JavaScript
		  + CleanedID + 'array[2] = "' + HTMLClr(FItemColor) + '";'#13
      + CleanedID + 'array[3] = "' + HTMLClr(FRootItemColor) + '";'#13
  		+ CleanedID + 'array[4] = "' + HTMLClrEx(FRootItemColorTo) + '";'#13
			+ CleanedID + 'array[5] = "' + HTMLClr(FRootItemBorderColor) + '";'#13;

		OpenMenu := '1';

		if (FOpen = moClick) then
			OpenMenu := '0';

		JavaScript := JavaScript
		  + CleanedID + 'array[6] = "' + OpenMenu + '";'#13
      + CleanedID + 'array[7] = "' + HTMLClr(FIconBackgroundColor) + '";'#13;

  	if (FHoverColorTo <> clNone) then
    begin
			if (FHoverGradientDirection = gdVertical) then
      begin
			  JavaScript := JavaScript
				  + CleanedID + 'array[8] = "none";'#13
					+ CleanedID + 'array[9] = "none";'#13
					+ CleanedID + 'array[10] = "' + GradDirToStr(FHoverGradientDirection) + '";'#13;
      end
			else
      begin
        ColorValue := ColorToRGB(FHoverColor);
        r := (ColorValue AND $FF);
        g := (ColorValue AND $FF00) shr 8;
        b := (ColorValue AND $FF0000) shr 16;
        ColorValue2 := ColorToRGB(HoverColorTo);
        r2 := (ColorValue2 AND $FF);
        g2 := (ColorValue2 AND $FF00) shr 8;
        b2 := (ColorValue2 AND $FF0000) shr 16;

        NewRed := Round(r * 0.9 + r2 * 0.1);
        NewGreen := Round(g * 0.9 + g2 * 0.1);
        NewBlue := Round(b * 0.9 + b2 * 0.1);
        NewColor := NewRed + (NewGreen shl 8) + (NewBlue shl 16);

        NewRed2 := Round(r * 0.1 + r2 * 0.9);
        NewGreen2 := Round(g * 0.1 + g2 * 0.9);
        NewBlue2 := Round(b * 0.1 + b2 * 0.9);
        NewColor2 := NewRed2 + (NewGreen2 shl 8) + (NewBlue2 shl 16);

        HoverColor3 := StringToColor(IntToStr(NewColor));
        HoverColor4 := StringToColor(IntToStr(NewColor2));

				JavaScript := JavaScript
				  + CleanedID + 'array[8] = "' + HTMLClr(HoverColor3) + '";'#13
					+ CleanedID + 'array[9] = "' + HTMLClr(HoverColor4) + '";'#13
					+ CleanedID + 'array[10] = "' + GradDirToStr(FHoverGradientDirection) + '";'#13;
      end;
    end
		else
    begin
		  JavaScript := JavaScript
			  + CleanedID + 'array[8] = "none";'#13
				+ CleanedID + 'array[9] = "none";'#13
				+ CleanedID + 'array[10] = "none";'#13;
    end;

    if (FAutoHiding) then
      JavaScript := JavaScript
        + CleanedID + 'array[11] = "true";'#13
    else
      JavaScript := JavaScript
        + CleanedID + 'array[11] = "false";'#13;

    {$IFDEF TMSIW6}
    if ((TIWComponent40Context(AContext).WebApplication.Browser <> brIE) or not(FBackgroundImage.Empty) or not (FUseBorder) or (FHoverColorTo <> clNone)) then
    {$ELSE}
    if ((WebApplication.Browser <> brIE) or (FHoverColorTo <> clNone) or not(FBackgroundImage.Empty) or not (FUseBorder)) then
    {$ENDIF}
      BdrWidth := '0';

    JavaScript := JavaScript
      + CleanedID + 'array[12] = "' + HTMLClr(FHoverFontColor) + '";'#13
      + CleanedID + 'array[13] = "' + HTMLClr(Font.Color) + '";'#13
      + CleanedID + 'array[14] = "' + BdrWidth + '";'#13
      + CleanedID + 'array[15] = "' + HTMLClr(FHoverBorderColor) + '";'#13;

    {$IFDEF TMSIW6}
    if (TIWComponent40Context(AContext).WebApplication.Browser = brIE) then
    {$ELSE}
    if (WebApplication.Browser = brIE) then
    {$ENDIF}
      JavaScript := JavaScript
        + CleanedID + 'array[16] = "' + IntToStr(FRootItemBorderWidth) + '";'#13
    else
      JavaScript := JavaScript
        + CleanedID + 'array[16] = "1";'#13;

    JavaScript := JavaScript
      + CleanedID + 'array[17] = "' + HTMLClr(FRootItemHoverFontColor) + '";'#13
      + CleanedID + 'array[18] = "' + HTMLClr(FRootItemFont.Color) + '";'#13
      + CleanedID + 'array[19] = "' + IntToStr(FOpacity) + '";'#13;

    {$IFDEF TMSIW6}
    if (TIWComponent40Context(AContext).WebApplication.Browser = brIE) then
    {$ELSE}
    if (WebApplication.Browser = brIE) then
    {$ENDIF}
      JavaScript := JavaScript
        + CleanedID + 'array[20] = "' + FadeToStr(Fade) + '";'#13
    else
      JavaScript := JavaScript
        + CleanedID + 'array[20] = "0";'#13;

    JavaScript := JavaScript
      + CleanedID + 'array[21] = "' + IIF(FShowIcons,'True','False') + '";'#13
      + CleanedID + 'array[22] = "' + IntToStr(ItemSpacing) + '";'#13;

    if not (FBackgroundImage.Empty) then
      JavaScript := JavaScript
        + CleanedID + 'array[23] = "True";'#13
    else
      JavaScript := JavaScript
        + CleanedID + 'array[23] = "False";'#13;

    IconColorTo := '';

    if (FIconBackgroundColorTo <> clNone) then
      IconColorTo := HTMLClr(FIconBackgroundColorTo);

    JavaScript := JavaScript
      + CleanedID + 'array[24] = "' + IconColorTo + '";'#13;

    JavaScript := JavaScript
      + CleanedID + 'array[25] = "' + HTMLClrEx(FRootItemHoverColor) + '";'#13
      + CleanedID + 'array[26] = "' + HTMLClrEx(FRootItemHoverColorTo) + '";'#13
      + CleanedID + 'array[27] = "' + HTMLClrEx(FRootItemBorderHoverColor) + '";'#13;

    if (FRootItemDownColor = clNone) then
    begin
      JavaScript := JavaScript
        + CleanedID + 'array[28] = "' + HTMLClrEx(FRootItemHoverColor) + '";'#13
        + CleanedID + 'array[29] = "' + HTMLClrEx(FRootItemHoverColorTo) + '";'#13;
    end
    else
    begin
      JavaScript := JavaScript
        + CleanedID + 'array[28] = "' + HTMLClrEx(FRootItemDownColor) + '";'#13
        + CleanedID + 'array[29] = "' + HTMLClrEx(FRootItemDownColorTo) + '";'#13;
    end;

    JavaScript := JavaScript
      + CleanedID + 'array[30] = "' + IIF((FRootItemGradientDirection = gdHorizontal),'1','0') + '";'#13
      + CleanedID + 'array[31] = "True";'#13
	    + 'getBrowser();'#13
		  + 'setProperties(' + CleanedID + 'array,''' + CleanedID + ''');'#13
      + 'startSideMenuBar(' + IntToStr(Width) + ',''' + CleanedID + 'arProp'',''' + CleanedID + 'array'',''' + FImgName + ''');'#13;

    for i := 1 to FMenu.Items.Count do
		begin
		  AItem := FMenu.Items[i-1];

      if (AItem.Visible) then
      begin
        arMenuId.Add(IntToStr(i));
        arMenuName.Add(IntToStr(i));
        URL := '';

        if (AItem.ImageIndex >= 0) and Assigned(FMenu.Images) and not (AItem.Checked) then
        begin
          if (FMenu.Images.Count > AItem.ImageIndex) then
          begin
            BMP := TBitmap.Create;
            FMenu.Images.BkColor := FIconBackgroundColor;
            FMenu.Images.GetBitmap(AItem.ImageIndex,BMP);
            URL := '';
            {$IFDEF TMSIW71}
            URL := TIWServerControllerBase.NewCacheFile('bmp',true);
            {$ELSE}
            URL := TIWServerControllerBase.NewCacheFile('bmp');
            {$ENDIF}
            BMP.SaveToFile(URL);
            URL := FCacheDir + ExtractFileName(URL);
            BMP.Free;
          end;
        end;

        Cap := AItem.Caption;
        Cap := StringReplace(Cap,'''','&#39;',[rfReplaceAll, rfIgnoreCase]);
        Cap := StringReplace(Cap,'<','&lt;', [rfReplaceAll, rfIgnoreCase]);
        Cap := StringReplace(Cap, '>','&gt;', [rfReplaceAll, rfIgnoreCase]);

        if (AItem.Count = 0) then
        begin
          if (FClientEvents.IndexOf(AItem.Name) >= 0) then
          begin
            JavaScript := javascript
              + 'function ' + CleanedID + '_' + IntToStr(i) + '(el) {'#13
              + '  hideAllMenus();'#13
              + '  ' + FClientEvents.Items[FClientEvents.IndexOf(AItem.Name)].FItemScript + #13
              + '  ' + CleanedID + 'SubmitValue(''' + CleanedID + '_'  + IntToStr(i) + ''')'#13
              + '}'#13;
          end;

          JavaScript := JavaScript
            + 'sideMenuLabelBlank(''' + Cap + ''',' + IntToStr(i) + ',' + IntToStr(Width)
            + ',''' + TextAlignToStr(TextAlignment) + ''',''' + CleanedID + '_' + IntToStr(i) + ''',''' + IntToStr(FRootItemHeight)
            + ''',''' + CleanedID + 'array'',''' + IIF((FClientEvents.IndexOf(AItem.Name) >= 0),'True','False') + ''',''' + URL + ''');'#13;
        end
        else
        begin
          if (FClientEvents.IndexOf(AItem.Name) >= 0) then
          begin
            JavaScript := javascript
              + 'function ' + CleanedID + '_' + IntToStr(i) + '(el) {'#13
              + '  ' + FClientEvents.Items[FClientEvents.IndexOf(AItem.Name)].FItemScript + #13
              + '  showSideMenu(''' + IntToStr(i) + ''',event,''' + TextAlignToStr(TextAlignment) + ''',''' + CleanedID + '_' + IntToStr(i) + ''',' + IntToStr(AItem.Count) + ');'#13
              + '}'#13;
          end;

          JavaScript := JavaScript
            + 'sideMenuLabel(''' + Cap + ''',' + IntToStr(i) + ',' + IntToStr(Width)
            + ',''' + TextAlignToStr(TextAlignment) + ''',''' + CleanedID + '_' + IntToStr(i) + ''',''' + IntToStr(FRootItemHeight)
            + ''',''' + CleanedID + 'array'',''' + IIF((FClientEvents.IndexOf(AItem.Name) >= 0),'True','False') + ''',''' + URL + ''',' + IntToStr(AItem.Count) + ');'#13;
        end;
      end;
		end;
                                                                
    JavaScript := JavaScript
      + 'endSideMenuBar();'#13
      + '</SCRIPT>'#13;

	  AutoNumber := FMenu.Items.Count;

	  JSSubMenu := '';

	  for i := 1 to FMenu.Items.Count do
    begin
		  Level := 0;
      MenuCode := '';
			AItem := FMenu.Items[i-1];

      if (AItem.Visible) then
      begin
			  JSSubMenu := JSSubMenu
			    + MakeMenu(IntToStr(i), AItem);
      end;
    end;

    submitclick :=  ' return SubmitClick('#39+HTMLName+#39+',name,' + #39 + 'false' + #39 + ');'#13;

    {$IFDEF TMSIW9}
    if Assigned(FOnAsyncMenuClick) then
    begin
      ajaxcall := 'processAjaxEvent(''onMenuClick1'', '
        + HTMLControlImplementation.IWCLName
        + ',''' + HTMLName + '.' + 'DoAsyncMenuClick' + ''','
        + 'true' + ', null, '
        + 'true' + ');';

        Acontext.WebApplication.RegisterCallBack(HTMLName+'.DoAsyncMenuClick', DoAsyncMenuClick);

        submitclick := '';
    end;                
   {$ENDIF}

		JSSubMenu := JSSubMenu
		  + 'function ' + CleanedID + 'SubmitValue(name)'#13
			+ '{'#13
      + 'document.getElementById("'+HTMLName+'_INPUT").value = name;'#13
      + ajaxcall
      + submitclick
			+ '}'#13;

    TiersArray := '';

    TiersArray := TiersArray
		  + '<SCRIPT>'#13
      + '  var ' + CleanedID + 'arProp = new Array();'#13;

    for k := 0 to Tiers.Count - 1 do
    begin
      if (Tiers[k] = 'null') then
			  TiersArray := TiersArray
				  + CleanedID + 'arProp[' + IntToStr(k) + '] = null;'#13
			else
				TiersArray := TiersArray
					+ CleanedID + 'arProp[' + IntToStr(k) + '] = ' + Tiers[k] + ';'#13;
    end;

		TiersArray := TiersArray
		  + '</SCRIPT>'#13;
  end;
  end;

  Tag := TIWHTMLTag.CreateTag('DIV');
  Tag.AddStringParam('class',HTMLName + 'CSS');
  Tag.AddStringParam('NAME',HTMLName);
  Tag.AddStringParam('ID',HTMLName);
  Tag.AddStringParam('STYLE', 'background-color:' + HTMLClr(Color));
  Parent := TIWHTMLTag.CreateTag('');
  Tag.Contents.AddText(Css);

  if not isPartial then
  begin
    Tag.Contents.AddText(TiersArray);
    checkNumberOfMenus := '';
    checkNumberOfMenus := '<SCRIPT>'#13
      + '  if (parseInt(' + IntToStr(Tiers.Count) + ') > parseInt(numMenus)) '#13
      + '    numMenus = ' + IntToStr(Tiers.Count) + ';'#13
      + '</SCRIPT>'#13;
    Tag.Contents.AddText(checkNumberOfMenus);

    Tag.Contents.AddText(JavaScript);
  end;

  if not (Assigned(FMenu)) or (FMenu.Items.Count = 0) then
  begin
      Tag.AddStringParam('STYLE', 'width:' + IntToStr(Self.Width) + ';background:' + HtmlClr(RootItemColor));
      Tag.Contents.AddText('&nbsp;');
  end;

  Scrpt := nil;
  if not isPartial then
  begin
    Scrpt := TIWHTMLTag.CreateTag('SCRIPT');
    Scrpt.Contents.AddText(JSSubMenu);
  end;


  {$IFDEF TMSIW6}
  Parent.Contents.Add(Tag);
  if not isPartial then
    Parent.Contents.Add(Scrpt);
  {$ENDIF}
  {$IFNDEF TMSIW6}
  Parent.Contents.AddTagAsObject(Tag);
  Parent.Contents.AddTagAsObject(Scrpt);
  {$ENDIF}

  Result := Parent;

  //clear arrays before refresh.
  //fixed: if some items are set to visible = false
  //after refresh the # of items in the array does no longer correspond to the
  //number of visible items and some subitems might not be displayed.
  arMenuId.Clear;
  arMenuName.Clear;  

  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName);
    AddStringParam('ID',HTMLName+'_INPUT');
  end;
end;

procedure TTIWSideMenu.BackgroundChanged(Sender: TObject);
begin
  Invalidate;
end;

{$IFDEF TMSIW6}
procedure TTIWSideMenu.IWPaint;
{$ELSE}
procedure TTIWSideMenu.Paint;
{$ENDIF}
var
  i: Integer;
  txt: string;
  r: TRect;
  BeginTop, SubHeight : integer;
begin
  r := GetClientRect;

  if Assigned(FMenu) then
  begin
    BeginTop := 0;
    SubHeight := FRootItemHeight;

    Canvas.Font.Name := FRootItemFont.FontName;
    Canvas.Font.Size := FRootItemFont.Size;
    Canvas.Font.Color := FRootItemFont.Color;
    Canvas.Font.Style := FRootItemFont.Style;

    for i := 1 to FMenu.Items.Count do
    begin
      txt := FMenu.Items[i - 1].Caption;

      with Canvas do
      begin
        r.Left := 0;
        r.Top := BeginTop;
        r.Right := Self.Width;
        r.Bottom := SubHeight;
        Pen.Color := RootItemBorderColor;
        Pen.Width := FRootItemBorderWidth;
        if (FRootItemColorTo <> clNone) then
        begin
          if (FRootItemGradientDirection = gdVertical) then
            DrawGradient(Canvas, FRootItemColor, FRootItemColorTo, 80, r, False)
          else
            DrawGradient(Canvas,FRootItemColor, FRootItemColorTo, 80, r, True);
          Brush.Style := bsClear;
          TextOut(Self.Width div 2 - TextWidth(txt) div 2, r.Top + ((SubHeight - BeginTop) div 2) - TextHeight(txt) div 2,txt);
        end
        else
        begin
          Brush.Color := FRootItemColor;
          TextRect(r,Self.Width div 2 - TextWidth(txt) div 2, r.Top + ((SubHeight - BeginTop) div 2) - TextHeight(txt) div 2, txt);
        end;
        Brush.Style := bsClear;
      end;
      BeginTop := BeginTop + FRootItemHeight;
      SubHeight := SubHeight + FRootItemHeight;
    end;

    if (FMenu.Items.Count = 0) then
    begin
      Canvas.Brush.Color := FRootItemColor;
      Canvas.Pen.Color := FRootItemBorderColor;
      Canvas.Pen.Width := FRootItemBorderWidth;
      Canvas.Rectangle(r.Left, r.Top, r.Left + Self.Width, r.Top + FRootItemHeight);
    end;
  end
  else
  begin
    Canvas.Brush.Color := FRootItemColor;
    Canvas.Pen.Color := FRootItemBorderColor;
    Canvas.Pen.Width := FRootItemBorderWidth;
    Canvas.Rectangle(r.Left, r.Top, r.Left + Self.Width, r.Top + FRootItemHeight);
  end;
end;

procedure TTIWSideMenu.DrawGradient(Canvas: TCanvas; FromColor, ToColor: TIWColor; Steps: Integer; r:TRect; Direction: Boolean);
var
  diffr,startr,endr: Integer;
  diffg,startg,endg: Integer;
  diffb,startb,endb: Integer;
  iend: Integer;
  rstepr,rstepg,rstepb,rstepw: Real;
  i,stepw: Word;

begin
  if Steps = 0 then
    Steps := 1;

  FromColor := ColorToRGB(FromColor);
  ToColor := ColorToRGB(ToColor);

  startr := (FromColor and $0000FF);
  startg := (FromColor and $00FF00) shr 8;
  startb := (FromColor and $FF0000) shr 16;
  endr := (ToColor and $0000FF);
  endg := (ToColor and $00FF00) shr 8;
  endb := (ToColor and $FF0000) shr 16;

  diffr := endr - startr;
  diffg := endg - startg;
  diffb := endb - startb;

  rstepr := diffr / steps;
  rstepg := diffg / steps;
  rstepb := diffb / steps;

  if Direction then
    rstepw := (R.Right - R.Left) / Steps
  else
    rstepw := (R.Bottom - R.Top) / Steps;

  with Canvas do
  begin
    for i := 0 to Steps - 1 do
    begin
      endr := startr + Round(rstepr*i);
      endg := startg + Round(rstepg*i);
      endb := startb + Round(rstepb*i);
      stepw := Round(i*rstepw);
      Pen.Color := endr + (endg shl 8) + (endb shl 16);
      Brush.Color := Pen.Color;
      if Direction then
      begin
        iend := R.Left + stepw + Trunc(rstepw) + 1;
        if iend > R.Right then
          iend := R.Right;
        Rectangle(R.Left + stepw,R.Top,iend,R.Bottom)
      end
      else
      begin
        iend := R.Top + stepw + Trunc(rstepw)+1;
        if iend > r.Bottom then
          iend := r.Bottom;
        Rectangle(R.Left, R.Top+stepw,R.Right,iend);
      end;
    end;
  end;
end;

procedure TTIWSideMenu.SetValue(const value:string);
begin
  FSelectedItem := value;
end;

procedure TTIWSideMenu.Submit(const AValue: string);
var
  Menu: TMenuItem;
begin
  Menu := StringToMenuItem(AValue);

  if Assigned(Menu) then
  begin
    {$IFDEF DELPHI6_LVL}
    if Menu.AutoCheck then
      Menu.Checked := not Menu.Checked;
    {$ENDIF}
    if Assigned(Menu.OnClick) then
       Menu.OnClick(Menu);
  end;
end;

procedure TTIWSideMenu.SetAutoHiding(const Value : Boolean);
begin
  FAutoHiding := Value;
end;

procedure TTIWSideMenu.SetBackgroundImage(const Value: TIPicture);
begin
  FBackgroundImage.Assign(Value);
  Invalidate;
end;

{$IFNDEF TMSIW71}
procedure TTIWSideMenu.SetDesignMode(const Value: Boolean);
begin
  FDesignMode := Value;
  Invalidate;
end;
{$ENDIF}

procedure TTIWSideMenu.SetFade(const Value : TTIWFade);
begin
  FFade := Value;
end;

procedure TTIWSideMenu.SetHoverGradientDirection(const Value : TTIWGradientDirection);
begin
  FHoverGradientDirection := Value;
end;

procedure TTIWSideMenu.SetIconBackgroundColor(const Value : TIWColor);
begin
  FIconBackgroundColor := Value;
end;

procedure TTIWSideMenu.SetIconBackgroundColorTo(const Value : TIWColor);
begin
  FIconBackgroundColorTo := Value;
end;

procedure TTIWSideMenu.SetItemColor(const Value: TIWColor);
begin
  FItemColor := Value;
end;

procedure TTIWSideMenu.SetItemHeight(const Value : Integer);
begin
  FItemHeight := Value;
end;

procedure TTIWSideMenu.SetMenu(const Value: TMenu);
begin
  FMenu := Value;
  Invalidate;
end;

procedure TTIWSideMenu.SetOpacity(const Value : Integer);
begin
  if (Value < 0) or (Value > 100) then
    raise Exception.Create('Value required between 0 and 100')
  else
  FOpacity := Value;
end;

procedure TTIWSideMenu.SetRootItemBorderColor(const Value : TIWColor);
begin
  FRootItemBorderColor := Value;
end;

procedure TTIWSideMenu.SetRootItemBorderHoverColor(const Value : TIWColor);
begin
  FRootItemBorderHoverColor := Value;
end;

procedure TTIWSideMenu.SetRootItemBorderWidth(const Value : integer);
begin
  FRootItemBorderWidth := Value;
end;

procedure TTIWSideMenu.SetRootItemColor(const Value: TIWColor);
begin
  FRootItemColor := Value;
end;

procedure TTIWSideMenu.SetRootItemColorTo(const Value: TIWColor);
begin
  FRootItemColorTo := Value;
end;

procedure TTIWSideMenu.SetRootItemHoverColor(const Value : TIWColor);
begin
  FRootItemHoverColor := Value;
end;

procedure TTIWSideMenu.SetRootItemHoverColorTo(const Value : TIWColor);
begin
  FRootItemHoverColorTo := value;
end;

procedure TTIWSideMenu.SetRootItemDownColor(const Value : TIWColor);
begin
  FRootItemDownColor := Value;
end;

procedure TTIWSideMenu.SetRootItemHeight(const Value : Integer);
begin
  FRootItemHeight := Value;
end;

procedure TTIWSideMenu.SetRootItemHoverFontColor(const Value : TIWColor);
begin
  FRootItemHoverFontColor := Value;
end;

procedure TTIWSideMenu.SetRootItemDownColorTo(const Value : TIWColor);
begin
  FRootItemDownColorTo := Value;
end;

procedure TTIWSideMenu.SetRootItemFont(const Value: TIWFont);
begin
  FRootItemFont.Assign(Value);
end;

procedure TTIWSideMenu.SetRootItemGradientDirection(const Value : TTIWGradientDirection);
begin
  FRootItemGradientDirection := Value;
end;

procedure TTIWSideMenu.SetSeparatorColor(const Value : TIWColor);
begin
  FSeparatorColor := Value;
end;

procedure TTIWSideMenu.SetSubMenuGlyph(const value: TIPicture);
begin
  FSubMenuGlyph.Assign(Value);
end;

procedure TTIWSideMenu.SetTextAlignment(const Value : TAlignment);
begin
  FTextAlignment := Value;
end;

procedure TTIWSideMenu.SetUseBorder(const Value : Boolean);
begin
  FUseBorder := Value;
end;

{ TTIWStaticMenu }
{$IFDEF TMSIW9}
procedure TTIWStaticMenu.DoAsyncItemClick(AParams: TStringList);
begin
  if Assigned(OnAsyncItemClick) then
    OnAsyncItemClick(Self, AParams, SelectedIndex);
end;

function TTIWStaticMenu.RenderAsync(
  AContext: TIWBaseHTMLComponentContext): TIWXMLTag;
begin
  Result := TIWXMLTag.CreateTag('control');
  try
    Result.AddStringParam('id', HTMLName);
    Result.AddStringParam('type', 'TTIWSTATICMENU');
    RenderAsyncCommonProperties( AContext, Result );
  except
    FreeAndNil(Result);
  end;
end;
{$ENDIF}

procedure TTIWStaticMenu.ItemsChanged(Sender: TObject);
begin
  Invalidate;
end;

constructor TTIWStaticMenu.Create(AOwner: TComponent);
begin
  inherited;
//  FItems := TStringLIst.Create;
//  FItems.OnChange := ItemsChanged;
  FItems := TTIWStaticMenuItems.Create(self);

  FColor := clWhite;
  FColorTo := clNone;
  FHoverColor := clInfoBk;
  FHoverColorTo := clNone;
  FHoverBorderColor := clBlack;
  FHoverBorderShadow := false;
  FBorderColor := clNone;
  FHoverFontColor := clBlack;
  Font.Color := clBlack;
  ic := TIWHTMLPictureCache.Create;
  ic.DesignLive := True;
  Width := 200;
  Height := 150;
  FDesignMode := True;
  {$IFDEF TMSIW6}
  SetRenderSize(True);
  {$ELSE}
  FRenderSize := True;
  FSupportsInput := True;
  FSupportsSubmit := True;
  {$ENDIF}

  ShowSelected := false;
  SelectedIndex :=  -1;
  SelectedColor := clInfoBk;
  SelectedColorTo := clNone;
  SelectedColorGradientDirection := gdHorizontal;
  SelectedFontColor := clBlack;
//  SelectedBorderColor := clNone;
  FixedColor := clWhite;
  FixedColorTo := clNone;
  FixedColorGradientDirection := gdHorizontal;
  FixedFontColor := clBlack;
  FixedBorderColor := clNone;
end;

destructor TTIWStaticMenu.Destroy;
begin
  FItems.Free;
  ic.Free;
  inherited;
end;

{$IFDEF TMSIW6}
procedure TTIWStaticMenu.IWPaint;
{$ELSE}
procedure TTIWStaticMenu.Paint;
{$ENDIF}
var
  fr: TRect;
  a,s,fa,sli,su:string;
  xsize,ysize,offsx,offsy,hl,ml,i: integer;
  hr:trect;

begin
  with Canvas do
  begin
    Font.Name := self.Font.FontName;
    Font.Size := Self.Font.Size;
    Brush.Style := bsSolid;
    Brush.Color := Self.Color;
    if FBorderColor <> clNone then
      Pen.Color := FBorderColor
    else
      Pen.Color := Brush.Color;
        
    Pen.Width := 1;
    Pen.Style := psSolid;

    Offsx := 0;
    Offsy := 0;

    for i := 1 to FItems.Count do
    begin
      sli := FItems[i - 1].Caption;

      Brush.Color := Self.Color;

      if pos('"#',sli) = 1 then
      begin
        delete(sli,1,2);
        su := copy(sli,1,pos('"',sli)-1);
        delete(sli,1,pos('"',sli));

        Brush.Color := TColor(StrToInt(su));
      end;

      if Layout = smlHorizontal then
        fr := Rect(0, 0, 1000, Height)
      else
        fr := Rect(0, 0, Width, 1000);

      HTMLDrawEx(Canvas, sli, fr, nil, 0,0,-1,-1,0,false,true,false,false,false,false,False,1.0,
        clBlue,clNone,clNone,clGray,a,s,fa,XSize,YSize,hl,ml,hr
        {$IFNDEF LINUX}
        ,ic,nil
        {$ENDIF}
        );

      if Layout = smlHorizontal then
        Rectangle(OffsX,0,OffsX + XSize + 10 ,Height)
      else
      begin
        if ItemHeight = 0 then
          Rectangle(0,OffsY,Width, OffsY + YSize)
        else
          Rectangle(0,OffsY,Width, OffsY + ItemHeight);
      end;


      if Layout = smlHorizontal then
        fr := Rect(OffsX + 2, 2, OffsX + XSize, Height)
      else
        fr := Rect(OffsX + 2, OffsY + 2, Width, OffsY + 1000);

      HTMLDrawEx(Canvas, sli, fr, nil, 0,0,-1,-1,0,false,false,false,false,false,false,True,1.0,
        clBlue,clNone,clNone,clGray,a,s,fa,XSize,YSize,hl,ml,hr

        {$IFNDEF LINUX}
        ,ic,nil
        {$ENDIF}
        );

      if Layout = smlHorizontal then
        OffsX := OffsX + XSize + 10
      else
      begin
        if (ItemHeight > 0) then
          OffsY := OffsY + ItemHeight
        else
          OffsY := OffsY + YSize;
      end;

    end;

    if FDesignMode then
    begin
      Brush.Style := bsClear;
      Pen.Style := psDot;
      Pen.Color := clBlack;
      Pen.Width := 1;
      Polygon([Point(0, 0), Point(Width - 1, 0), Point(Width - 1, Height - 1), Point(0, Height - 1)]);
      Pen.Style := psSolid;
    end;
  end;
end;

procedure TTIWStaticMenu.SetValue(const value:string);
begin
   inherited SetValue(value);

   if (value <> '') then
     SelectedIndex := StrToInt(value);
end;


{$IFDEF TMSIW6}
function TTIWStaticMenu.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
{$ELSE}
function TTIWStaticMenu.RenderHTML: TIWHTMLTag;
{$ENDIF}
var
  i: Integer;
  clicktag, movertag, mouttag: string;
//  ItemColor: TIWColor;
  sli,su: string;
  html:string;
  HeightItem : string;
  gDir: string;
  ajaxcall: string;

begin
   {$IFDEF TMSIW9}
   if Assigned(FOnAsyncItemClick) then
   begin
      ajaxcall := 'processAjaxEvent(''onItemClick'', '
        + HTMLControlImplementation.IWCLName
        + ',''' + HTMLName + '.' + 'DoAsyncItemClick' + ''','
        + 'true' + ', null, '
        + 'true' + ');';
     Acontext.WebApplication.RegisterCallBack(HTMLName+'.DoAsyncItemClick', DoAsyncItemClick);
   end;
   {$ENDIF}

  if (Layout = smlVertical) then
  begin
  if (ItemHeight > 0) then
    HeightItem := 'height="' + IntToStr(ItemHeight) + 'px" '
  else
    HeightItem := '';
  end;

  html :=
   '<style type="text/css">'#13
   + '<!--'#13
   + '.'+HTMLName+'menu {font-family:'+iif(Font.FontName='','Arial',Font.FontName)+'; font-size:'+IntToStr(Font.Size)+'pt; '
//   + ' border:solid; border-width:1;
   + '}'#13
   + '.'+HTMLName+'menu a{'#13
   + 'text-decoration:none;'#13
   + 'color:'+HTMLClr(Font.Color)+';'#13
   + '}'#13
   + '-->'#13
   + '</style>'#13
   + '<script language="javascript">'#13
   + '<!--'#13

   + 'function '+HTMLName+'SetSel(index){'#13
   + 'var previndex = document.getElementById("'+HTMLName+'_INPUT").value;'#13
   + 'document.getElementById("'+HTMLName+'_INPUT").value = index;'#13
   + HTMLName + 'moveout(document.getElementById("'+HTMLName+'it" + previndex),"","","",previndex);'#13
   + '}'#13;

 for i := 1 to FItems.Count do
  begin
    html := html
     + 'function '+HTMLName+'ClientCode'+IntToStr(i - 1)+'(idx,server,fixed,which){'#13
     + 'if (! fixed){'#13
     +   HTMLName+'SetSel(idx);'#13     
     + '  ' + HTMLName+'select(which);'#13
     +   Items[i - 1].FClientClick + #13
     +   ajaxcall + #13
     + '}'#13
     + 'if (server == true)'#13
     + '  return SubmitClick("'+HTMLName+'",idx,"false");'#13
     + '}'#13
  end;

   html := html
   + 'function '+HTMLName+'movein(which){'#13
   + 'if (which)'#13
   + '{'#13;

  if HoverColorTo <> clNone then
  begin

    if FHoverColorGradientDirection = gdHorizontal then
      gDir := '1'
    else
      gDir := '0';

      html := html + 'which.style.filter="progid:DXImageTransform.Microsoft.Gradient(GradientType='
        +gDir+',StartColorStr='+HTMLClr(FHoverColor)+', EndColorStr='+HTMLClr(FHoverColorTo)+')";'#13;
    end;

    html := html

     + '  which.style.backgroundColor='#39+HTMLClr(FHoverColor)+#39';'#13

     + iif(FHoverBorderColor = clNone, '', '  which.style.borderColor='#39+HTMLClr(FHoverBorderColor) + #39';'#13)

     + '  which.style.color='#39+HTMLClr(FHoverFontColor)+#39';'#13
     + IIF (FHoverBorderShadow, '  which.style.borderBottom='' 2 outset'';'#13)
     + IIF (FHoverBorderShadow, '  which.style.borderRight='' 2 outset'' ;'#13)

     + iif(FHoverBorderColor = clNone, '  which.style.borderWidth='#39+'0'+#39';'#13, '  which.style.borderWidth='#39+'1'+#39';'#13)
     + iif(FHoverBorderColor = clNone, '  which.style.borderStyle=''none'';'#13, '  which.style.borderStyle=''solid'';'#13)

      {*
     + '  which.firstChild.style.backgroundColor='#39+HTMLClr(FHoverColor)+#39';'#13
     + '  which.firstChild.style.borderColor='#39+HTMLClr(FHoverBorderColor)+#39';'#13
     + '  which.firstChild.firstChild.style.color='#39+HTMLClr(FHoverFontColor)+#39';'#13
     + '  which.firstChild.style.borderWidth='#39+'1'+#39';'#13
     + '  which.firstChild.style.borderStyle=''solid'';'#13
     + '  which.style.borderWidth='#39+'0'+#39';'#13
     + '  which.style.borderStyle='''';'#13
     + '  which.style.borderColor='''';'#13
     + IIF (FHoverBorderShadow, '  which.firstChild.style.borderBottom='' 2 outset'';'#13)
     + IIF (FHoverBorderShadow, '  which.firstChild.style.borderRight='' 2 outset'' ;'#13)
     *}
     + '}'#13
     + '}'#13#13
     
     + 'function '+HTMLName+'moveout(which,bkcol,grsel,fcol,idx){'#13
     + 'if (which)'#13
     + '{'#13
     + ' if ((idx == document.getElementById("'+HTMLName+'_INPUT").value) && ('+iif(ShowSelected,'true','false') +')) '#13
     + '  '+HTMLName+'select(which);'#13
     + ' else'#13
     + ' {'#13

     + '  which.style.filter='''';'#13
     + '  which.style.backgroundColor='''';'#13
     + '  which.style.borderColor='#39+HTMLClr(FBorderColor)+#39#13
     + '  which.style.color=fcol;'#13
     + '  which.style.borderWidth='#39+'0'+#39';'#13
     + '  which.style.borderStyle=''solid'';'#13

     {*
     + '  which.firstChild.style.filter='''';'#13
     + '  which.style.filter='''';'#13
     + '  which.firstChild.style.backgroundColor='''';'#13
     + '  which.style.backgroundColor=''transparent'';'#13
     //   + 'which.firstChild.style.borderColor='#39+HTMLClr(FBorderColor)+#39#13
     + '  which.firstChild.firstChild.style.color=fcol;'#13
     + '  which.firstChild.style.borderWidth='#39+'0'+#39';'#13
     + '  which.firstChild.style.borderStyle=''solid'';'#13
     *}

     + '  }'#13
     + ' }'#13
     + '}'#13#13

     + 'function '+HTMLName+'select(which)'#13
     + '{'#13
     
     + 'if ((which) && ('+iif(ShowSelected,'true','false') +'))'#13
     + '{'#13;

  if (SelectedColorTo <> clNone) then
  begin
     if FSelectedColorGradientDirection = gdHorizontal then
      gDir := '1'
    else
      gDir := '0';
     html := html
       + 'which.style.filter="progid:DXImageTransform.Microsoft.Gradient(GradientType='
         +gDir+',StartColorStr='+HTMLClr(FSelectedColor)+', EndColorStr='+HTMLClr(FSelectedColorTo)+')";'#13;
  end
  else
    html := html + '  which.style.filter="";'#13;

  html := html
  + '  which.style.backgroundColor='''+HTMLClr(FSelectedColor)+''';'#13
  + '  which.style.color='''+HTMLClr(FSelectedFontColor)+''';'#13
  + '  which.style.borderWidth='#39+'1px'+#39';'#13
  + '  which.style.borderStyle=''solid'';'#13
  + '  which.style.borderColor=''black'';'#13

  {*
  + '  which.firstChild.style.backgroundColor='''+HTMLClr(FSelectedColor)+''';'#13
  + '  which.firstChild.firstChild.style.color='''+HTMLClr(FSelectedFontColor)+''';'#13
  + '  which.firstChild.style.borderWidth='#39+'1'+#39';'#13
  + '  which.firstChild.style.borderStyle=''solid'';'#13
  + '  which.style.borderWidth='#39+'0'+#39';'#13
  + '  which.style.borderStyle='''';'#13
  + '  which.style.borderColor='''';'#13
  *}
  + '}'#13  
  + '}'#13
  + '//-->'#13
  + '</script>'#13;

    if FColorGradientDirection = gdHorizontal then
      gDir := '1'
    else
      gDir := '0';

  html := html
    + '<table width="100%" frame="border" rules="none" border="0" cellspacing="0" cellpadding="0"'
    + IIF (FColorTo <> clNone, ' style="border-collapse:collapse;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType='+gDir+',StartColorStr='
      + HTMLClr(FColor)+', EndColorStr='+HTMLClr(FColorTo)+');', 'style="border-collapse:collapse;background-color:'+HTMLClr(FColor))
    + '">';
  if Layout = smlHorizontal then
    html := html + '<tr>';

  for i := 1 to FItems.Count do
  begin

    clicktag := ' onclick="'+HTMLName+'ClientCode'+IntToStr(i - 1)+'('+IntToStr(i - 1)+',';

    if (Assigned(FOnClick) and ( not FItems[i - 1].FFixed) )then
      clicktag := clicktag + 'true'
    else
      clicktag := clicktag + 'false';

    if (FItems[i - 1].FFixed) then
      clicktag := clicktag + ',true'
    else
      clicktag := clicktag + ',false';

    clicktag := clicktag + ' ,this);"';


    sli := FItems[i - 1].Caption;
    if pos('"#',sli) = 1 then
    begin
      delete(sli,1,2);
      su := copy(sli,1,pos('"',sli)-1);
      delete(sli,1,pos('"',sli));
    end;


    if Layout = smlVertical then
      html := html + '<tr>';

    html := html
      + '<td id="it' + IntToStr(i - 1) + '" ' + HeightItem
      + ' class="'+HTMLName+'menu"'
      + ' style="';

    if FFixedColorGradientDirection = gdHorizontal then
      gDir := '1'
    else
      gDir := '0';

    if (FItems[i - 1].FFixed) then
    begin
      if (FFixedColor <> clNone) then
      begin
        if (FFixedColorTo <> clNone) then
          html := html + ' filter:progid:DXImageTransform.Microsoft.Gradient(GradientType='+gDir+',StartColorStr='
           + HTMLClr(FFixedColor)+', EndColorStr='+HTMLClr(FFixedColorTo)+');';

        //else
        //show backgroundColor in FF
          html := html + ' background-color:'+HTMLClr(FFixedColor)+';'
      end
      else
        html := html + ' background-color:transparent;';
      if (FFixedBorderColor <> clNone) then
//        html := html + ' border-width:1;border-style:solid;border-color:'+HTMLClr(FFixedBorderColor)+';'
        html := html + ' border:1px solid '+HTMLClr(FFixedBorderColor)+';'
      else
        html := html + ' border-color:transparent;';
      if (FFixedFontColor <> clNone) then
        html := html + ' color:'+HTMLClr(FFixedFontColor)+';';
    html := html + 'cursor:default"';
    end

    else if ((SelectedIndex = i - 1) and ShowSelected) then
    begin
      html := html + 'cursor:pointer;';
     if (FSelectedColor <> clNone) then
      begin
        if (FSelectedColorTo <> clNone) then
        begin
          if FSelectedColorGradientDirection = gdHorizontal then
            gDir := '1'
          else
            gDir := '0';
          html := html + ' filter:progid:DXImageTransform.Microsoft.Gradient(GradientType='+gDir+',StartColorStr='
           + HTMLClr(FSelectedColor)+', EndColorStr='+HTMLClr(FSelectedColorTo)+');'
        end;
        html := html + ' background-color:'+HTMLClr(FSelectedColor)+';'
      end
      else
        html := html + ' background-color:transparent;';

      if (FSelectedFontColor <> clNone) then
        html := html + ' color:'+HTMLClr(FSelectedFontColor)+';';

    html := html + '"';

      if (FSelectedColor <> clNone) then
      begin
        mouttag := ' onmouseout="'+HTMLName+'moveout(this,'''+HTMLClr(FSelectedColor)+'''';
        if (FSelectedColorTo <> clNone) then
          mouttag := mouttag + ',1'
        else
          mouttag := mouttag + ',0';
      end
      else
        mouttag := ' onmouseout="'+HTMLName+'moveout(this,''transparent''';
      if (FSelectedFontColor <> clNone) then
        mouttag := mouttag + ','''+HTMLClr(FSelectedFontColor)+''','+IntToStr(i-1)+')"'
      else
        mouttag := mouttag + ','''+HTMLClr(Font.Color)+''','+IntToStr(i-1)+')"';
     movertag := movertag + ' onmouseover="'+HTMLName+'movein(this)"';
     end

    else
    begin
      html := html + 'cursor:pointer;';
      html := html + ' background-color:transparent;';
      if BorderColor <> clNone then
//        html := html + ' border-style:solid;border-color:'+HTMLClr(BorderColor);
        html := html + ' border:1px solid '+HTMLClr(BorderColor);
      html := html + '"';
      mouttag := ' onmouseout="'+HTMLName+'moveout(this,''transparent'',0,'''
        +HTMLClr(font.Color)+''','+IntToStr(i-1)+')"';
      movertag := ' onmouseover="'+HTMLName+'movein(this)"';
    end;

    html := html
      + '>'
      + '<div style="width:100%;height:100%;">'
      + '<table cellpadding="0" cellspacing="0" border="0" style="width:100%;height:100%;color:';
    if (FItems[i - 1].FFixed) then
    begin
      if (FFixedFontColor <> clNone) then
        html := html + HTMLClr(FFixedFontColor)
      else
        html := html + HTMLClr(Font.Color);
    end

    else if ((SelectedIndex = i - 1) and ShowSelected) then
    begin
      if (FSelectedFontColor <> clNone) then
        html := html + HTMLClr(FSelectedFontColor)
      else
        html := html + HTMLClr(Font.Color)
    end
    else
    begin
      html := html + HTMLClr(Font.Color);
    end;

    html := html
      + ';font-size:'+IntToStr(Font.Size)+'pt;'
      + '">'
      + '<tr>'
      + '<td id="'+HTMLName+'it'+ IntToStr(i - 1) +'" style="overflow:hidden;width:100%;height:100%;text-indent:3;'
      + iif( ((SelectedIndex = i - 1) and ShowSelected ),'border:1px solid black;','')
      + '" '
      + iif((not (FItems[i - 1].FFixed)) , movertag + mouttag, '')
      + clicktag + ' align="left" valign="middle">'
      + sli + '</td>'
      + '</tr>'
      + '</table>'
      + '</div>'
      + '</td>';

    if Layout = smlVertical then
      html := html + '</tr>';

      end;

  if Layout = smlHorizontal then
    html := html + '</tr>';

  html := html + '</table>';

  Result := TIWHTMLTag.CreateTag('DIV');
  Result.Contents.AddText(html);
//  if (BorderColor <> clNone) then
//    Result.AddStringParam('STYLE','border-width:1;border-style:solid;border-color:'+HTMLClr(BorderColor)+'');

    with Result.Contents.AddTag('INPUT') do
    begin
      AddStringParam('TYPE','hidden');
      AddStringParam('NAME',HTMLName);
      AddStringParam('VALUE',IntToStr(SelectedIndex));
      AddStringParam('ID',HTMLName+'_INPUT');
    end;

end;

procedure TTIWStaticMenu.SetBaseDir(const Value: string);
begin
  FBaseDir := Value;
  ic.BaseDir := Value;
end;

procedure TTIWStaticMenu.SetBorderColor(const Value: TIWColor);
begin
  FBorderColor := Value;
  Invalidate;
end;

procedure TTIWStaticMenu.SetColor(const Value: TIWColor);
begin
  FColor := Value;
  Invalidate;
end;

procedure TTIWStaticMenu.SetColorTo(const Value: TIWColor);
begin
  FColorTo := Value;
  Invalidate;
end;

procedure TTIWStaticMenu.SetDesignLive(const Value: Boolean);
begin
  FDesignLive := Value;
  ic.DesignLive := Value;
end;

procedure TTIWStaticMenu.SetItemHeight(const Value : Integer);
begin
  FItemHeight := Value;
  Invalidate;
end;

{$IFNDEF TMSIW71}
procedure TTIWStaticMenu.SetDesignMode(const Value: Boolean);
begin
  FDesignMode := Value;
  Invalidate;
end;
{$ENDIF}

procedure TTIWStaticMenu.SetHoverBorderColor(const Value: TIWColor);
begin
  FHoverBorderColor := Value;
  Invalidate;
end;

procedure TTIWStaticMenu.SetHoverColor(const Value: TIWColor);
begin
  FHoverColor := Value;
  Invalidate;
end;

                                                                      //Bart ->
procedure TTIWStaticMenu.SetHoverColorTo(const Value: TIWColor);
begin
  FHoverColorTo := Value;
  Invalidate;
end;

procedure TTIWStaticMenu.SetLayout(const Value: TStaticMenuLayout);
begin
  FLayout := Value;
  Invalidate;
end;

procedure TTIWStaticMenu.Submit(const AValue: string);
var
  V,Err: Integer;
begin
  if Assigned(FOnClick) then
  begin
    val(AValue,v,err);
    FOnClick(Self,v);
  end;
end;

function TTIWStaticMenu.HTMLClr(color: TIWColor):string;
begin
  Result := ColorToRGBString(ColorToRGB(color));
end;


{ TMenuClientEvent }

procedure TMenuClientEvent.Assign(Source: TPersistent);
begin
  FItemName := (Source as TMenuClientEvent).ItemName;
  FItemScript := (Source as TMenuClientEvent).ItemScript;
end;

constructor TMenuClientEvent.Create(Collection: TCollection);
begin
  inherited;
end;

destructor TMenuClientEvent.Destroy;
begin
  inherited;
end;

{ TMenuClientEvents }

function TMenuClientEvents.Add: TMenuClientEvent;
begin
  Result := TMenuClientEvent(inherited Add);
end;

constructor TMenuClientEvents.Create;
begin
  inherited Create(TMenuClientEvent);
end;

function TMenuClientEvents.GetItem(Index: Integer): TMenuClientEvent;
begin
  Result := TMenuClientEvent(inherited Items[Index]);
end;

function TMenuClientEvents.IndexOf(ItemName: string): Integer;
var
  i: integer;
begin
  Result := -1;
  for i := 1 to Count do
  begin
    if Uppercase(Items[i - 1].ItemName) = UpperCase(ItemName) then
    begin
      Result := i - 1;
      Break;
    end;
  end;

end;

function TMenuClientEvents.Insert(Index: Integer): TMenuClientEvent;
begin
  Result := TMenuClientEvent(inherited Insert(Index));
end;

procedure TMenuClientEvents.SetItem(Index: Integer;
  const Value: TMenuClientEvent);
begin
  inherited SetItem(Index,Value);
end;

{ TTIWStaticMenuItems }

function TTIWStaticMenuItems.Add: TTIWStaticMenuItem;
begin
  Result := TTIWStaticMenuItem(inherited Add);
end;

constructor TTIWStaticMenuItems.Create(AOwner: TTIWStaticMenu);
begin
  inherited Create(TTIWStaticMenuItem);
  FOwner := AOwner;
end;

function TTIWStaticMenuItems.GetItem(Index: Integer): TTIWStaticMenuItem;
begin
  Result := TTIWStaticMenuItem(inherited Items[Index]);
end;

function TTIWStaticMenuItems.Insert(Index: Integer): TTIWStaticMenuItem;
begin
  Result := TTIWStaticMenuItem(inherited Insert(Index));
end;

procedure TTIWStaticMenuItems.SetItem(Index: Integer;
  const Value: TTIWStaticMenuItem);
begin
  inherited Items[Index] := Value;
end;

{ TTIWStaticMenuItem }

procedure TTIWStaticMenuItem.Assign(Source: TPersistent);
begin
  FCaption := (Source as TTIWStaticMenuItem).Caption;
  FClientClick := (Source as TTIWStaticMenuItem).ClientClick;
  FFixed := (Source as TTIWStaticMenuItem).Fixed;
end;

procedure TTIWStaticMenuItem.SetCaption(Value: string);
begin
  FCaption := Value;
  (Collection as TTIWStaticMenuItems).FOwner.Invalidate;
end;

end.




