{***************************************************************************}
{ TMS IntraWeb Component Pack Pro                                           }
{ for Delphi & C++Builder                                                   }
{                                                                           }
{ written by TMS Software                                                   }
{            copyright © 2002 - 2007                                        }
{            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 IWOutlookBar;
                                                       
interface                                           
                                                   
{$I TMSDEFS.INC}                                     
uses                                                  
  {$IFDEF LINUX}
  QGraphics, QImgList, QControls,
  {$ELSE}
  Controls, Windows, Graphics, IWPicCntnr, IWTMSImg, Menus,
  {$ENDIF}
  {$IFDEF DELPHI6_LVL}
  Types,
  {$ENDIF}
  Classes, Math,
  IWControl, IWTypes, IWFont, IWFileReference, IWScriptEvents, IWHTMLTag,
  SysUtils, IWTMSBase
  {$IFDEF TMSIW51}
  , IWColor
  {$ENDIF}
  {$IFDEF TMSIW6}
  , IWRenderContext
  {$ENDIF}
  {$IFDEF TMSIW9}
  , IWXMLTag
  {$ENDIF}  
  ;

type
  TIWOutlookItem = class;
  TIWOutlookPanel = class;
  TTIWOutlookBar = class;

  TIWGradientDirection = (gdHorizontal, gdVertical);

  TIWPanelChangeClick = procedure(ASender: TObject; const Panel: TIWOutlookPanel) of object;

  TIWItemOutlookBarClick = procedure(ASender: TObject; Panel: TIWOutlookPanel;
    Item: TIWOutlookItem) of object;

  TIWItemIndexOutlookBarClick = procedure(ASender: TObject; const Panel: Integer;
    const Item: Integer) of object;

  {$IFDEF TMSIW9}
  TIWAsyncPanelChangeEvent = procedure (Sender: TObject; EventParams: TStringList; const Panel: TIWOutlookPanel) of object;
  TIWAsyncItemOutlookBarEvent = procedure (Sender: TObject; EventParams: TStringList; Panel: TIWOutlookPanel;
    Item: TIWOutlookItem) of object;
  TIWAsyncItemIndexOutlookBarEvent = procedure (Sender: TObject; EventParams: TStringList; const Panel: Integer;
    const Item: Integer) of object;
  {$ENDIF}

  TIWOutlookItem = class(TCollectionItem)
  private
    FCaption: string;
    FScript : string;
    FLink : string;
    FBitmap: TBitmap;
    FBitmapURL: string;
    FImageIndex: integer;
    FHint: string;
    FTag: Integer;
    procedure SetCaption(const Value: string);
    procedure SetBitmap(const Value: TBitmap);
    procedure SetScript(const Value : string);
    procedure SetLink(const Value : string);
    function GetBitmap: TBitmap;
    procedure SetImageIndex(const Value: integer);
    function GetOutlookBar: TTIWOutlookBar;
    function GetOutlookPanel: TIWOutlookPanel;
  protected
    procedure Changed;
    function GetDisplayName: string; override;
  public
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
    property OutlookPanel: TIWOutlookPanel read GetOutlookPanel;
    property OutlookBar: TTIWOutlookBar read GetOutlookBar;
  published
    property Bitmap: TBitmap read GetBitmap write SetBitmap;
    property BitmapURL: string read FBitmapURL write FBitmapURL;
    property Caption: string read FCaption write SetCaption;
    property Hint: string read FHint write FHint;
    property ImageIndex: integer read FImageIndex write SetImageIndex default - 1;
    property Link : string read FLink write SetLink;
    property Script : string read FScript write SetScript;
    property Tag: Integer read FTag write FTag;
  end;

  TIWOutlookItems = class(TOwnedCollection)
  private
    FOwner: TIWOutlookPanel;
    function GetItem(Index: integer): TIWOutlookItem;
    procedure SetItem(Index: integer; const Value: TIWOutlookItem);
  protected
    procedure Update(Item: TCollectionItem); override;
  public
    function CreateItemClass: TCollectionItemClass; virtual;
    constructor Create(AOwner: TIWOutlookPanel);
    function Add: TIWOutlookItem;
    function Insert(index: integer): TIWOutlookItem;
    property Items[Index: integer]: TIWOutlookItem read GetItem write SetItem; default;
  published
  end;

  TIWOutlookPanel = class(TCollectionItem)
  private
    FItems: TIWOutlookItems;
    FCaption: string;
    FImageIndex: integer;
    FScript :string;
    FTag: Integer;
    procedure SetOutlookItems(const Value: TIWOutlookItems);
    procedure SetCaption(const Value: string);
    procedure SetScript(const Value : string);
    function GetOutlookBar: TTIWOutlookBar;
    procedure SetImageIndex(const Value: integer);
  protected
    function GetDisplayName: string; override;
  public
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
    function CreateItems: TIWOutlookItems; virtual;
    property OutlookBar: TTIWOutlookBar read GetOutlookBar;
  published
    property Caption: string read FCaption write SetCaption;
    property ImageIndex: integer read FImageIndex write SetImageIndex default - 1;
    property Items: TIWOutlookItems read FItems write SetOutlookItems;
    property Script : string read FScript write SetScript;
    property Tag: Integer read FTag write FTag;
  end;

  TIWOutlookPanels = class(TOwnedCollection)
  private
    FOwner: TTIWOutlookBar;
    function GetItem(Index: integer): TIWOutlookPanel;
    procedure SetItem(Index: integer; const Value: TIWOutlookPanel);
  protected
    procedure Update(Item: TCollectionItem); override;
  public
    function CreateItemClass: TCollectionItemClass; virtual;
    constructor Create(AOwner: TTIWOutlookBar);
    function Add: TIWOutlookPanel;
    function Insert(index: integer): TIWOutlookPanel;
    property Items[Index: integer]: TIWOutlookPanel read GetItem write SetItem; default;
  published
  end;

  TTIWOutlookBar = class(TIWControl)
  private
    FActivePanel: Integer;
    FBackgroundGradientDirection : TIWGradientDirection;
    FBorderColor: TIWColor;
    FBorderSize: Integer;
    FButtonColor : TIWColor;
    FButtonColorTo : TIWColor;
    FButtonFont: TIWfont;
    FButtonGradientDirection : TIWGradientDirection;
    FButtonHeight : Integer;
    FColor: TIWColor;
    FColorTo : TIWColor;
    FFirstItem : Integer;
    FHoverColor: TIWColor;
    FImages: TImageList;
    FImageBorderColor : TIWColor;
    FImageHeight : Integer;
    FImageWidth : Integer;
    FItemFont: TIWfont;
    FItemHeight: Integer;
    FItemSpace: Integer;
    FItemWidth: Integer;
    FLabelMargin: Integer;
    FMargin: Integer;
    FOpenCloseSpeed: Integer;
    FPanels: TIWOutlookPanels;
    FUseTemplate : Boolean;
    FArrowSlideSpeed: integer;

    FOnItemClick: TIWItemOutlookBarClick;
    FOnItemIndexClick: TIWItemIndexOutlookBarClick;
    FOnPanelChange : TIWPanelChangeClick;
    FClickedElement: string;

    {$IFDEF TMSIW9}
    FOnAsyncPanelChange: TIWAsyncPanelChangeEvent;
    FOnAsyncItemClick: TIWAsyncItemOutlookBarEvent;
    FOnAsyncItemIndexClick: TIWAsyncItemIndexOutlookBarEvent;
    procedure DoAsyncPanelChange(AParams: TStringList);
    procedure DoAsyncItemClick(AParams: TStringList);
    {$ENDIF}

    procedure SetActivePanel(const Value: Integer);
    procedure SetBackgroundGradientDirection (const Value : TIWGradientDirection);
    procedure SetBorderColor(const Value: TIWColor);
    procedure SetBorderSize(const Value: Integer);
    procedure SetButtonColor(const Value : TIWColor);
    procedure SetButtonColorTo(const Value : TIWColor);
    procedure SetButtonFont(const Value: TIWfont);
    procedure SetButtonGradientDirection(const Value : TIWGradientDirection);
    procedure SetButtonHeight(const Value : Integer);
    procedure SetColor(const Value: TIWColor);
    procedure SetColorTo(const Value : TIWColor);
    procedure SetImageBorderColor(const Value : TIWColor);
    procedure SetImageHeight(const Value : integer);
    procedure SetImageWidth(const Value : integer);
    procedure SetItemFont(const Value: TIWfont);
    procedure SetItemHeight(const Value: integer);
    procedure SetItemSpace(const Value: integer);
    procedure SetItemWidth(const Value: integer);
    procedure SetIWOutlookPanels(const Value: TIWOutlookPanels);
    procedure SetLabelMargin(const Value: Integer);
    procedure SetMargin(const Value: integer);
    procedure SetUseTemplate(const Value : Boolean);
  protected
    function PathBmp(var bmp:TBitmap): string;
    function HTMLClr(color: TIWColor): string;
    procedure Draw3DCtrl(FCanvas: TCanvas; Left, Top, Right, Bottom: integer;
      ColorUp,ColorDn: TIWColor;penwidth:integer);
    procedure InvalidateItem(Panel: TIWOutlookPanel; Item: TIWOutlookItem);
    procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
    procedure Submit(const AValue: string); override;
  public
    procedure SetValue(const AValue: String); override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function CreatePanels: TIWOutlookPanels; virtual;
    {$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}
    function Htmlbmp(bmp: TBitmap):string;
  published
    property ActivePanel: Integer read FActivePanel write SetActivePanel;
    property BackgroundGradientDirection : TIWGradientDirection read FBackgroundGradientDirection write SetBackgroundGradientDirection;
    property BorderColor :TIWColor read FBorderColor write SetBorderColor default $dddddd;
    property BorderSize: Integer read FBorderSize write SetBorderSize default 3;
    property ButtonColor : TIWColor read FButtonColor write SetButtonColor;
    property ButtonColorTo : TIWColor read FButtonColorTo write SetButtonColorTo;
    property ButtonFont : TIWfont read FButtonFont write SetButtonFont;
    property ButtonGradientDirection : TIWGradientDirection read FButtonGradientDirection write SetButtonGradientDirection;
    property ButtonHeight : Integer read FButtonHeight write SetButtonHeight;
    property Color: TIWColor read FColor write SetColor default clBlack;
    property ColorTo : TIWColor read FColorTo write SetColorTo default clBlack;
    property HoverColor: TIWColor read FHoverColor write FHoverColor;
    property Images: TImageList read FImages write FImages;
    property ImageBorderColor : TIWColor read FImageBorderColor write SetImageBorderColor;
    property ImageHeight : Integer read FImageHeight write SetImageHeight;
    property ImageWidth : Integer read FImageWidth write SetImageWidth;
    property ImageMargin: Integer read FMargin write SetMargin default 4;
    property ItemFont : TIWfont read FItemFont write SetItemFont;
    property ItemHeight: Integer read FItemHeight write SetItemHeight default 32;
    property ItemSpace: Integer read FItemSpace write SetItemSpace default 8;
    property ItemWidth: Integer read FItemWidth write SetItemWidth default 32;
    property LabelMargin: Integer read FLabelMargin write SetLabelMargin default 3;
    property OpenCloseSpeed: Integer read FOpenCloseSpeed write FOpenCloseSpeed;
    property Panels: TIWOutlookPanels read FPanels write SetIWOutlookPanels;
    property ScrollSpeed:integer read FArrowSlideSpeed write FArrowSlideSpeed default 8;
    property UseTemplate : boolean read FUseTemplate write SetUseTemplate;
    property OnItemClick: TIWItemOutlookBarClick read FOnItemClick write FOnItemClick;
    property OnItemIndexClick: TIWItemIndexOutlookBarClick read FOnItemIndexClick write FOnItemIndexClick;
    property OnPanelChange : TIWPanelChangeClick read FOnPanelChange write FOnPanelChange;
    {$IFDEF TMSIW9}
    property OnAsyncPanelChange: TIWAsyncPanelChangeEvent read FOnAsyncPanelChange write FOnAsyncPanelChange;
    property OnAsyncItemClick: TIWAsyncItemOutlookBarEvent read FOnAsyncItemClick write FOnAsyncItemClick;
    property OnAsyncItemIndexClick: TIWAsyncItemIndexOutlookBarEvent read FOnAsyncItemIndexClick write FOnAsyncItemIndexClick;        
    {$ENDIF}
  end;

implementation
{$R tmsiwoutlookbar.res}

uses
  IWAppForm, IWForm, IWServerControllerBase,                                            
  SWSystem, SWStrings, IWServer;

{ TTIWOutlookBar }
{$IFDEF TMSIW9}
procedure TTIWOutlookBar.DoAsyncPanelChange(AParams: TStringList);
var
Panel: integer;
begin
  Panel := StrToInt(FClickedElement);

  ActivePanel := Panel;

  if Assigned(OnAsyncPanelChange) then
    OnAsyncPanelChange(Self, AParams, FPanels[Panel]);
end;

procedure TTIWOutlookBar.DoAsyncItemClick(AParams: TStringList);
var
Item: integer;
begin
  Item := StrToInt(FClickedElement);

  if Assigned(OnAsyncItemClick) then
    OnAsyncItemClick(Self, AParams, FPanels[ActivePanel], FPanels[ActivePanel].Items[Item]);

  if Assigned(OnAsyncItemIndexClick) then
    OnAsyncItemIndexClick(Self, AParams, ActivePanel, Item);
end;

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

constructor TTIWOutlookBar.Create(AOwner: TComponent);
begin
  inherited;

  {$IFDEF TMSIW6}
  {TODO}
  {$ELSE}
  FSupportsSubmit := True;
  FSupportsInput := True;
  {$ENDIF}

  FPanels := CreatePanels;
  FItemHeight := 40;
  FItemWidth := 40;
  FImageWidth := 24;
  FImageHeight := 24;  
  FLabelMargin := 2;
  
  FColor := clInfoBk;
  FColorTo := clInactiveBorder;

  FArrowSlideSpeed := 8;

  FOpenCloseSpeed := 3;
  FItemSpace := 8;
  FMargin := 0;
  FBorderColor := $dddddd;
  FBorderSize := 1;
  FHoverColor := clRed;
  {$IFDEF TMSIW6}
  SetRenderSize(True);
  {$ELSE}
  FRenderSize := True;
  {$ENDIF}

  FActivePanel := 0;
  FFirstItem := 0;
  FUseTemplate := false;

  SetBounds(left, top, 120, 360);

  FButtonFont := TIWFont.Create;
  FButtonFont.FontName := 'Arial';
  FButtonFont.Color := clBlack;
  FButtonFont.Size := 10;
  FButtonColor := clBtnFace;
  FButtonColorTo := clNone;
  FButtonHeight := 20;

  FItemFont := TIWFont.Create;
  FItemFont.FontName := 'Arial';
  FItemFont.Color := clBlack;
  FItemFont.Size := 10;

  {$IFDEF TMSIW6}
  {TODO}
  {$ELSE}
  FSupportedScriptEvents := 'OnClick,OnAbort,OnError,OnKeyDown,OnKeyPress,OnKeyUp,OnLoad';
  {$ENDIF}
end;

destructor TTIWOutlookBar.Destroy;
begin
  inherited;
  FButtonFont.Free;
  FItemFont.Free;
  FPanels.Free;
end;

function TTIWOutlookBar.CreatePanels: TIWOutlookPanels;
begin
  Result := TIWOutlookPanels.Create(Self);
end;

procedure TTIWOutlookBar.Draw3DCtrl(FCanvas: TCanvas; Left, Top, Right,
  Bottom: integer; ColorUp,ColorDn: TIWColor;penwidth:integer);
begin
  if PenWidth = 0 then
    Exit;
  with FCanvas do
  begin
    Pen.Color := ColorUp;
    pen.Width := PenWidth;
    PenWidth := Round((PenWidth / 2))+1;
    MoveTo(Left + PenWidth, Bottom - PenWidth);
    LineTo(Left + PenWidth, Top + PenWidth);
    LineTo(Right - PenWidth, Top + PenWidth);

    Pen.Color := ColorDn;
    LineTo(Right - PenWidth, Bottom - PenWidth);
    LineTo(Left + PenWidth, Bottom - PenWidth);
  end;
end;

procedure TTIWOutlookBar.InvalidateItem(Panel: TIWOutlookPanel;
  Item: TIWOutlookItem);
begin
  if csLoading in ComponentState then
    Exit;
  Invalidate;
end;

procedure TTIWOutlookBar.Notification(AComponent: TComponent;
  AOperation: TOperation);
begin
  inherited;
  if (AOperation = opRemove) and (AComponent = FImages) then
  begin
    FImages := nil;
    Invalidate;
  end;
end;

{$IFDEF TMSIW6}
procedure TTIWOutlookBar.IWPaint;
{$ELSE}
procedure TTIWOutlookBar.Paint;
{$ENDIF}
var
  i: integer;
  r,dr: Trect;
  dx1, dx2, hitem: integer;
  s: string;
  dy: Integer;
begin
  inherited;
  Canvas.Pen.Color := clBlack;
  Canvas.Brush.Color := color;
  Canvas.Rectangle(ClientRect);
  Draw3DCtrl(Canvas, 0, 0, Width, Height, FBorderColor, FBorderColor, FBorderSize);

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

  //--------- Draw Panels -----------
  for i := 0 to FPanels.Count - 1 do
  begin
    if i <= ActivePanel then
    begin
      dy := 0;
//      r := Rect(0, dy + (i) * FPanelHeight + 1 + FBorderSize, Width,
//                   dy + (i + 1) * FPanelHeight + 1 + FBorderSize);
      r := Rect(0, dy + (i) * FButtonHeight + 1 + FBorderSize, Width,
                   dy + (i + 1) * FButtonHeight + 1 + FBorderSize);


    end
    else
    begin
//      dy := Height - (FPanels.Count - (ActivePanel)) * PanelHeight;
      dy := Height - (FPanels.Count - (ActivePanel)) * ButtonHeight;
//      r := Rect(0, dy + (i - ActivePanel) * FPanelHeight + 1 + FBorderSize, Width,
//                   dy + (i + 1 - ActivePanel) * FPanelHeight + 1 + FBorderSize);
      r := Rect(0, dy + (i - ActivePanel) * FButtonHeight + 1 + FBorderSize, Width,
                   dy + (i + 1 - ActivePanel) * FButtonHeight + 1 + FBorderSize);

    end;

    //visible left and right border
    InflateRect(r,-FBorderSize -1,0);

    Canvas.Brush.Color := clBtnFace;
    Canvas.Rectangle(r.Left + 1,r.Top + 1,r.Right - 1,r.Bottom - 1);

    Draw3DCtrl(Canvas,r.Left,r.Top,r.Right,r.Bottom,clWhite,clGray,1);

    Inflaterect(r,-2,-2);
    {$IFNDEF LINUX}
    DrawText(Canvas.Handle,pchar(FPanels[i].Caption),Length(FPanels[i].Caption),r,DT_CENTER or DT_VCENTER);
    {$ENDIF}

  end;

  //-------- Draw Items --------------------
  // top limit
  dx1 :=  FButtonHeight * (ActivePanel + 1) + FBorderSize + FMargin;

  // bottom limit
  dx2 := Height - (FPanels.Count -  (ActivePanel + 1)) * FButtonHeight - FMargin - FBorderSize;

  hitem := FItemHeight + FItemSpace;

  r.Left := (Width div 2) - (FItemWidth div 2);
  r.Right := (Width div 2) + (FItemWidth div 2);
  r.Top := dx1 + 2;

  if FPanels.Count > 0 then
    for i := 0 to FPanels[FActivePanel].FItems.Count - 1 do
    begin
      Canvas.Font.Color := FItemFont.Color;
      Canvas.Font.Name := FItemFont.FontName;
      Canvas.Font.Size := FItemFont.Size;
      Canvas.Font.Style := FItemFont.Style;

      r.Bottom := r.Top + hitem - Canvas.TextHeight('gh');
      s := FPanels[FActivePanel].FItems[i].Caption;
      if Assigned(FImages) then
      begin
        if (FPanels[FActivePanel].FItems[i].ImageIndex>-1) and (FImages.Count>FPanels[FActivePanel].FItems[i].ImageIndex) then
        begin
          FImages.Draw(Canvas, R.Left, R.Top + FMargin, FPanels[FActivePanel].FItems[i].ImageIndex);
          r.Bottom := r.Top + FImageHeight + FMargin;
        end;
      end
      else
      begin
        if not FPanels[FActivePanel].FItems[i].Bitmap.Empty then
        begin
          Canvas.Draw(R.Left, R.Top + FMargin, FPanels[FActivePanel].FItems[i].Bitmap);
          r.Bottom := r.Top + FImageHeight + FMargin;
        end;
      end;

      Canvas.Pen.Style := psClear;
      Canvas.Brush.Color := Color;

      dr := Rect(FBorderSize * 2,r.Bottom + FLabelMargin, Width - 2 * FBorderSize,r.Bottom + FLabelMargin + ItemHeight);

      {$IFNDEF LINUX}
      DrawText(Canvas.Handle,PChar(s),length(s),dr,DT_CENTER or DT_TOP);
      {$ENDIF}

      Canvas.Pen.Style := psSolid;
      r.Top := r.Top + hitem;

      if r.Top + hItem  >= dx2 then
        Break;
    end;
end;

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

function TTIWOutlookBar.pathbmp(var bmp:TBitmap):string;
begin
  Result := '';

  if not Assigned(bmp) then
    bmp := TBitmap.Create;

  if bmp.Empty then
  begin
    bmp.Width := FItemWidth;
    bmp.Height := FItemHeight;
    bmp.canvas.Brush.Color := FColor;
    bmp.Canvas.FillRect(Rect(0,0,FItemWidth,FItemHeight));
  end;

  {$IFDEF TMSIW71}
  Result := TIWServerControllerBase.NewCacheFile('bmp',true);
  {$ELSE}
  Result := TIWServerControllerBase.NewCacheFile('bmp');
  {$ENDIF}

  bmp.TransparentMode := tmAuto;
  bmp.Transparent := True;
  bmp.SaveToFile(Result);

  Result := GetCacheDir(Self) + ExtractFilename(Result)
end;

function TTIWOutlookBar.Htmlbmp(bmp: TBitmap):string;
var
  spath: string;
begin
  Result := '';
  if not Assigned(bmp) then
    Exit;
  if bmp.Empty then
    Exit;

  {$IFDEF TMSIW71}
  spath := TIWServerControllerBase.NewCacheFile('bmp',true);
  {$ELSE}
  spath := TIWServerControllerBase.NewCacheFile('bmp');
  {$ENDIF}
  bmp.SaveToFile(spath);
  spath := GetCacheDir(Self) + ExtractFileName(spath);
  Result := spath;
end;

procedure TTIWOutlookBar.SetActivePanel(const Value: Integer);
begin
  if not (csLoading in ComponentState) then
  begin
    if (Value < 0) or (Value > Panels.Count) then
      raise exception.Create('Active panel index out of range');
  end;

  FActivePanel := Value;
  Invalidate;
end;

{$IFDEF TMSIW6}
function TTIWOutlookBar.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
{$ELSE}
function TTIWOutlookBar.RenderHTML: TIWHTMLTag;
{$ENDIF}
var
  html : string;
  s    : string;
  BackColor : TIWColor;
  GradDir : string;
  ScrollImageUp : string;
  ScrollImageDown : string;
  i,j, k : integer;
  PanelImage : string;
  bmp : TBitmap;
  itemIm : string;
  renderImgTag, caption : string;
  ajaxcall, submitclick: string;
begin
  {$IFDEF TMSIW6}
  if not (AContext.WebApplication.Browser = brIE) then
    TIWComponent40Context(AContext).AddToInitProc('document.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT | Event.CLICK);');
  {$ELSE}
  if not (WebApplication.Browser = brIE) then
    AddToInitProc('document.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT | Event.CLICK);');
  {$ENDIF}

  html := GetResourceText('tmsiwoutlookbar');

  html := StringReplace(html, 'outlookbar', HTMLName, [rfIgnoreCase, rfReplaceAll]);

  s := HTMLName + '_Height = ' + IntToStr(Self.Height) + ';'#13
    +  HTMLName + '_HeightContent = ' + IntToStr(Self.Height - FPanels.Count * FButtonHeight - 2 * FBorderSize) + ';'#13
    +  HTMLName + '_PanelHeight = ' + IntToStr(Self.Height - FPanels.Count * FButtonHeight - 2 * FBorderSize) + ';'#13
    +  HTMLName + '_Width = ' + IntToStr(Self.Width) + ';'#13
    +  HTMLName + '_ItemHeight = ' + IntToStr(Self.ItemHeight) + ';'#13
    +  HTMLName + '_ItemHeightDiv = ' + IntToStr(Self.ItemHeight - 2) + ';'#13
    +  HTMLName + '_ActivePanel = ' + IntToStr(FActivePanel) + ';'#13
    +  HTMLName + '_ButtonHeight = ' + IntToStr(FButtonHeight) + ';'#13

    +  HTMLName + '_ActiveItem = ' + IntToStr(FFirstItem) + ';'#13;

  if (Color = clNone) then
    BackColor := clGray
  else
    BackColor := FColor;

  s := s
    + HTMLName + '_BackgroundColor = ''' + HTMLClr(BackColor) + ''';'#13;

  if (FColorTo = clNone) then
  begin
    s := s
      + HTMLName + '_PanelColor = ''background:' + HTMLClr(BackColor) + ''''#13;
  end
  else
  begin
    GradDir := '1';

    if (BackgroundGradientDirection = gdVertical) then
      GradDir := '0';

    s := s
      + HTMLName + '_PanelColor = ''background:' + HTMLClr(BackColor) + ';filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=' + GradDir + ',StartColorStr='
      + HTMLClr(BackColor) + ',EndColorStr=' + HTMLClr(ColorTo) + ')'';'#13;
  end;

  s := s
    + HTMLName + '_BorderSize = ' + IntToStr(BorderSize) + ';'#13
    + HTMLName + '_ButtonHeight = ' + IntToStr(ButtonHeight) + ';'#13
    + HTMLName + '_BorderColor = ''' + HTMLClr(BorderColor) + ''';'#13;

  if (ButtonColorTo = clNone) then
  begin
    s := s
      + HTMLName + '_ButtonColor = ''background:' + HTMLClr(ButtonColor) + ''';'#13;
  end
  else
  begin
    GradDir := '1';                                                         
    if (ButtonGradientDirection = gdVertical) then                  
      GradDir := '0';

      s := s
        + HTMLName + '_ButtonColor = ''background:' + HTMLClr(ButtonColor) + ';filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=' + GradDir + ',StartColorStr='
      + HTMLClr(ButtonColor) + ',EndColorStr=' + HTMLClr(ButtonColorTo) + ')'';'#13;
  end;

  if (ButtonFont.FontName <> '') then                                     
    s := s
      + HTMLName + '_ButtonFontFamily = ''' + ButtonFont.FontName + ''';'#13
  else
    s := s
      + HTMLName + '_ButtonFontFamily = ''' + Font.FontName + ''';'#13;

  if (ButtonFont.Size <> 0) then
    s := s
      + HTMLName + '_ButtonFontSize = ' + IntToStr(ButtonFont.Size) + ';'#13
  else
    s := s
      + HTMLName + '_ButtonFontSize = ' + IntToStr(Font.Size) + ';'#13;

  s := s
    + HTMLName + '_ButtonFontColor = ''' + HTMLClr(ButtonFont.Color) + ''';'#13;

  if (fsBold in ButtonFont.Style) then
    s := s
      + HTMLName + '_ButtonFontBold = true;'#13
  else
    s := s
      + HTMLName + '_ButtonFontBold = false;'#13;

  if (fsItalic in ButtonFont.Style) then
    s := s
      + HTMLName + '_ButtonFontItalic = true;'#13
  else
    s := s
      + HTMLName + '_ButtonFontItalic = false;'#13;


  if (fsUnderline in ButtonFont.Style) then
    s := s
      + HTMLName + '_ButtonFontUnderline = true;'#13
  else
    s := s
      + HTMLName + '_ButtonFontUnderline = false;'#13;

  s := s
    + HTMLName + '_ButtonCSSStyle = '''';'#13
    + HTMLName + '_tabScrollSpeed = ' + IntToStr(FOpenCloseSpeed) + ';'#13;


  if (ItemFont.FontName <> '') then
    s := s
      + HTMLName + '_LabelFontFamily = ''' + ItemFont.FontName + ''';'#13
  else
    s := s
      + HTMLName + '_LabelFontFamily = ''' + Font.FontName + ''';'#13;

  if (ButtonFont.Size <> 0) then
    s := s
      + HTMLName + '_LabelFontSize = ' + IntToStr(ItemFont.Size) + ';'#13
  else
    s := s
      + HTMLName + '_LabelFontSize = ' + IntToStr(Font.Size) + ';'#13;

  s := s
    + HTMLName + '_LabelFontColor = ''' + HTMLClr(ItemFont.Color) + ''';'#13;

  if (fsBold in ItemFont.Style) then
    s := s
      + HTMLName + '_LabelFontBold = true;'#13
  else
    s := s
      + HTMLName + '_LabelFontBold = false;'#13;

  if (fsItalic in ItemFont.Style) then
    s := s
      + HTMLName + '_LabelFontItalic = true;'#13
  else
    s := s
      + HTMLName + '_LabelFontItalic = false;'#13;


  if (fsUnderline in ItemFont.Style) then
    s := s
      + HTMLName + '_LabelFontUnderline = true;'#13
  else
    s := s
      + HTMLName + '_LabelFontUnderline = false;'#13;


  s := s
    + HTMLName + '_LabelCSSStyle = '''';'#13
    + HTMLName + '_ColorOver = ''' + HTMLClr(HoverColor) + ''';'#13
    + HTMLName + '_ColorNormal = ''' + HTMLClr(ItemFont.Color) + ''';'#13
    + HTMLName + '_ItemPicHeight = ' + IntToStr(ImageHeight) + ';'#13
    + HTMLName + '_ItemPicHeightDiv = ' + IntToStr(ImageHeight) + ';'#13
    + HTMLName + '_ItemPicHeightImg = ' + IntToStr(ImageHeight - 4) + ';'#13

    + HTMLName + '_ItemPicWidth = ' + IntToStr(ImageWidth) + ';'#13
    + HTMLName + '_ItemPicWidthDiv = ' + IntToStr(ImageWidth) + ';'#13
    + HTMLName + '_ItemPicWidthImg = ' + IntToStr(ImageWidth - 4) + ';'#13
    + HTMLName + '_ItemPicMargin = ' + IntToStr(ImageMargin) + ';'#13
    + HTMLName + '_ItemPicMarginDiv = ' + IntToStr(ImageMargin - 2) + ';'#13
    + HTMLName + '_ItemSpacing = ' + IntToStr(ItemSpace) + ';'#13
    + HTMLName + '_ItemSpacingDiv = ' + IntToStr(ItemSpace - 2) + ';'#13
    + HTMLName + '_LabelMargin = ' + IntToStr(LabelMargin) + ';'#13
    + HTMLName + '_LabelMarginDiv = ' + IntToStr(LabelMargin - 2) + ';'#13
    + HTMLName + '_HeightText = ' + IntToStr(ItemHeight - ItemSpace - LabelMargin - ImageHeight - ImageMargin) + ';'#13
    + HTMLName + '_HeightTextDiv = ' + IntToStr(ItemHeight - ItemSpace - LabelMargin - ImageHeight - ImageMargin - 2) + ';'#13
    + HTMLName + '_itemScrollSpeed = ' + IntToStr(FArrowSlideSpeed) + ';'#13;

  s := s
    + 'var butpos = ''''; '#13
		+ 'if (ns){ '#13
		+ '  butpos = "position:absolute;top:"+document.getElementById('''+HTMLName+''').style.top+";left:"+document.getElementById('''+HTMLName+''').style.left+'';''; '#13
		+ '}'#13;


 	  ScrollImageUp := '<span id="' + HTMLName + '_ScrollUp" onmouseover="' + HTMLName + 'scrollMouseOver(this);" onmouseout="'
                    + HTMLName + 'scrollMouseOut(this);" style="cursor:pointer;cursor:hand;''+butpos+''height:16;width:16;background:' + HTMLClr(clBtnFace)
                    + ';text-align:center;align:top;border-top: 1px solid buttonface; border-left:1px solid buttonface;'
                    + 'border-bottom:1px solid buttonface; border-right:1 solid buttonface";>'
                   + '<FONT face="Webdings">5</FONT></span>';

   ScrollImageDown := '<span id="' + HTMLName + '_ScrollDown" onmouseover="' + HTMLName + 'scrollMouseOver(this);" onmouseout="'
                    + HTMLName + 'scrollMouseOut(this);" style="cursor:pointer;cursor:hand;''+butpos+''height:16;width:16;background:' + HTMLClr(clBtnFace)
                    + ';text-align:center;align:top;border-top: 1px solid buttonface; border-left:1px solid buttonface;'
                    + 'border-bottom:1px solid buttonface; border-right:1 solid buttonface";>'
                   + '<FONT face="Webdings"><div style="overflow:hidden;height:16;width:16;">6</div></FONT></span>';

  s := s
    + HTMLName + '_ScrollButtonUp = ''' + ScrollImageUp + ''';'#13
    + HTMLName + '_ScrollButtonDown = ''' + ScrollImageDown + ''';'#13
    + HTMLName + '_ScrollButtonHeight = 16;'#13
    + HTMLName + '_ImageBorderColor = ''' + HtmlClr(ImageBorderColor) + ''';'#13
    + HTMLName + '_numberOfPanels = ' + IntToStr(FPanels.Count) + ';'#13
    + HTMLName + '_ScrollButtonWidth = 16;'#13
    + HTMLName + 'Items = new Array();'#13;

    for k := 0 to Panels.Count - 1 do
      s := s
        + HTMLName + 'Items[' + IntToStr(k) + '] = ' + IntToStr(Panels[k].Items.Count) + ';'#13;

  html := StringReplace(html, '<#SETTINGS>', s, [rfReplaceAll, rfIgnoreCase]);

  s := HTMLName + '_start();'#13;

  s := s
    + 'function ' + HTMLName + 'scrollMouseOver(el) {'#13
    + '  el.style.borderTop = "1px solid buttonhighlight";'#13
    + '  el.style.borderLeft = "1px solid buttonhighlight";'#13
    + '  el.style.borderRight = "1px solid buttonshadow";'#13
    + '  el.style.borderBottom = "1px solid buttonshadow";'#13
    + '}'#13                                                               
    + 'function ' + HTMLName + 'scrollMouseOut(el) {'#13
    + '  el.style.borderTop = "1px solid buttonface";'#13
    + '  el.style.borderLeft = "1px solid buttonface";'#13
    + '  el.style.borderRight = "1px solid buttonface";'#13
    + '  el.style.borderBottom = "1px solid buttonface";'#13
    + '}'#13;

  for j := 0 to FPanels.Count - 1 do
  begin

    if (Assigned (OnPanelChange)) then
      submitclick := 'return SubmitClick(''' + HTMLName + ''',''CHANGE' + IntToStr(j)+ '#0'',''' + ''',getTopItem(),''false'');'#13
    else
      submitclick := '';

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

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

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

    s := s
      + 'function activepanel_' + HTMLName + '_' + IntToStr(j)+ '() {'#13
      + FPanels[j].Script
      + 'document.getElementById("'+HTMLName+'_INPUT").value = ' + IntToStr(j) + ';'#13      
      + ajaxcall
      + submitclick
      + '}'#13;

    PanelImage := '';

    if ((FPanels[j].ImageIndex >= 0) and Assigned(Images)) then
    begin
      if Images.Count > FPanels[j].ImageIndex then
      begin
        bmp := TBitmap.Create;

        bmp.Width := Images.Width;
        bmp.Height := Images.Height;
        bmp.Canvas.Brush.Color := self.ButtonColor;
        bmp.Canvas.Pen.Color := self.ButtonColor;
        bmp.Canvas.Rectangle(0,0,Images.Width,Images.Height);
        Images.Draw(bmp.Canvas,0,0,FPanels[j].ImageIndex);

        PanelImage := HTMLBmp(bmp);
        PanelImage := '<img border="0" src="' + PanelImage +'" align="middle">&nbsp;';
        bmp.Free;
      end;
    end;

    caption := TextToHTML(FPanels[j].Caption);
    caption := StringReplace(caption,'"','&quot;',[rfReplaceAll]);
    caption := StringReplace(caption,'''','&#39',[rfReplaceAll]);

    s := s
      + 'outlooktab_start(''' + PanelImage + ''',''' + caption + ''',''JSCRIPT:activepanel_' + HTMLName+ '_' + IntToStr(j) + '()' + ''');'#13;

    for i := 0 to FPanels[j].Items.Count - 1 do
    begin
      if (FPanels[j].Items[i].Caption <> '') then
      begin

          if (Assigned(OnItemClick) or Assigned(OnItemIndexClick)) then
            submitclick := '  return SubmitClick(''' + HTMLName + ''',''ITEMCLICK' + IntToStr(j) + '#' + IntToStr(i) + ''',''' + ''',getTopItem(),''false'');'#13
          else
            submitclick := '';

          {$IFDEF TMSIW9}
          if (Assigned(OnAsyncItemClick) or Assigned(OnAsyncItemIndexClick)) then
          begin
            ajaxcall := 'processAjaxEvent(''onItemClick'', '
              + HTMLControlImplementation.IWCLName
              + ',''' + HTMLName + '.' + 'DoAsyncItemClick' + ''','
              + 'true' + ', null, '
              + 'true' + ');';

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

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

        s := s
          + 'function itemclick_' + HTMLName + '_' + IntToStr(j) + '_' + IntToStr(i) + '() {'#13
          + FPanels[j].Items[i].Script
          + 'document.getElementById("'+HTMLName+'_INPUT").value = ' + IntToStr(i) + ';'#13
          + ajaxcall
          + submitclick
          + '}'#13;

        itemIm := '';

        if (FPanels[j].Items[i].ImageIndex >= 0) and Assigned(Images) then
        begin
          if Images.Count > FPanels[j].Items[i].ImageIndex then
          begin
            bmp := TBitmap.Create;

            bmp.Width := Images.Width;
            bmp.Height := Images.Height;

            bmp.Canvas.Brush.Color := self.Color;
            bmp.Canvas.Pen.Color := self.Color;
            bmp.Canvas.Rectangle(0,0,Images.Width,Images.Height);

            Images.Draw(bmp.Canvas,0,0,FPanels[j].Items[i].ImageIndex);

         //   Images.BkColor := clNone;
          //  Images.GetBitmap(FPanels[j].Items[i].ImageIndex,bmp);
            itemIm := HTMLBmp(bmp);
            bmp.Free;
          end;
        end;

        if (FPanels[j].Items[i].BitmapURL <> EmptyStr) then
          itemIm := FPanels[j].Items[i].BitmapURL
        else if (FPanels[j].Items[i].ImageIndex = -1) and not FPanels[j].Items[i].Bitmap.Empty then
        begin
          itemIm := HTMLBmp(FPanels[j].Items[i].Bitmap);
        end;


        if (ItemIm <> '') then
          RenderImgTag := '1'
        else
          RenderImgTag := '0';

    caption := TextToHTML(FPanels[j].Items[i].Caption);
    caption := StringReplace(caption,'"','&quot;',[rfReplaceAll]);
    caption := StringReplace(caption,'''','&#39',[rfReplaceAll]);

        s := s
          + 'outlooktab_additem(''' + RenderImgTag + ''',''' + caption + ''',''' + FPanels[j].Items[i].Link + ''',''' + itemIm + ''',''' +
          TextToHTML(FPanels[j].Items[i].Hint) + ''',''JScript:itemclick_' + HTMLName + '_' + IntToStr(j) + '_' + IntToStr(i) + '()'');'#13;
      end;
    end;
    s := s                                                                                 
      + 'outlooktab_end();'#13;
  end;                                                                             

  if (UseTemplate) then
  begin
    s := s
//    + HTMLName + '_end(''true'');'+HTMLName+'_ativateTab(0,true);</script>';
   + HTMLName + '_end(''true'');'+HTMLName+'_ativateTab(' + inttostr(FActivePanel) + ',true);</script>';
  end
  else
  begin
  s := s
//    + HTMLName + '_end(''false'');'+HTMLName+'_ativateTab(0,true);</script>';
    + HTMLName + '_end(''false'');'+HTMLName+'_ativateTab(' + inttostr(FActivePanel) + ',true);</script>';
  end;

  html := html + s;

  Result := TIWHTMLTag.CreateTag('DIV');
  Result.Contents.AddText(html);
  with Result.Contents.AddTag('INPUT') do                  
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName);
    AddStringParam('ID',HTMLName+'_INPUT');
  end;
end;

procedure TTIWOutlookBar.SetImageBorderColor(const Value : TIWColor);
begin
  FImageBorderColor := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetUseTemplate(const Value : Boolean);
begin
  FUseTemplate := Value;
end;

procedure TTIWOutlookBar.SetButtonColor(const Value : TIWColor);
begin
  FButtonColor := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetButtonColorTo(const Value : TIWColor);
begin
  FButtonColorTo := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetButtonGradientDirection(const Value : TIWGradientDirection);
begin
  FButtonGradientDirection := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetButtonHeight(const Value : Integer);
begin
  if (Value < 1) then
    raise Exception.Create('Value required > 0')
  else
    FButtonHeight := Value;

  Invalidate;
end;

procedure TTIWOutlookBar.SetColor(const Value: TIWColor);
begin
  Fcolor := Value;
  Invalidate;
end;

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

procedure TTIWOutlookBar.SetImageHeight(const Value : Integer);
begin
  FImageHeight := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetImageWidth(const Value : Integer);
begin
  FImageWidth := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetItemHeight(const Value: integer);
begin
  FItemHeight := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetItemWidth(const Value: integer);
begin
  FItemWidth := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetIWOutlookPanels(const Value: TIWOutlookPanels);
begin
  FPanels := Value;
end;

procedure TTIWOutlookBar.SetBackgroundGradientDirection(const Value : TIWGradientDirection);
begin
  FBackgroundGradientDirection := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetValue(const AValue: String);
begin
  FClickedElement := Avalue;
  //  FStateString := AValue;
end;

procedure TTIWOutlookBar.Submit(const AValue: string);
var
  s: string;
  Panel: integer;
  Item: integer;
  temp : string;
begin
  s := AValue;

  if (pos('CHANGE',s) > 0) then
  begin
    s := Copy(s,7,Length(s)-6);
    s := Copy(s,0,pos('#',s)-1);
    Panel := StrToInt(s);
    if (Panel < FPanels.Count) then
    begin
      FActivePanel := Panel;
      if (Assigned(OnPanelChange)) then
        OnPanelChange(Self,FPanels[Panel]);
    end;
  end
  else
  begin
    if (pos('ITEMCLICK',s) > 0) then
    begin
      temp := Copy(s,10,length(s)-9);
      temp := Copy(temp,0,pos('#',temp)-1);
      Panel := StrToInt(temp);
      if (Panel < FPanels.Count) then
      begin
        FActivePanel := Panel;
        temp := Copy(s,10,length(s)-9);
        temp := Copy(temp,pos('#',temp) + 1,Length(temp)-pos('#',temp));
        Item := StrToInt(temp);
        if (Item < FPanels[Panel].Items.Count) then
        begin
          if (Assigned(OnItemClick)) then
            OnItemClick(Self,FPanels[Panel],FPanels[Panel].Items[Item]);

          if (Assigned(OnItemIndexClick)) then
            OnItemIndexClick(Self, Panel, Item);
        end;
      end;
    end;
  end;
end;

procedure TTIWOutlookBar.SetButtonFont(const Value: TIWfont);
begin
  FButtonFont.assign(Value);
  Invalidate;
end;

procedure TTIWOutlookBar.SetItemFont(const Value: TIWfont);
begin
  FItemFont.assign(Value);
  Invalidate;
end;

procedure TTIWOutlookBar.SetLabelMargin(const Value: Integer);
begin
  FLabelMargin := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetMargin(const Value: integer);
begin
  FMargin := Value;
  Invalidate;
end;

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

procedure TTIWOutlookBar.SetItemSpace(const Value: integer);
begin
  FItemSpace := Value;
  Invalidate;
end;

procedure TTIWOutlookBar.SetBorderSize(const Value: Integer);
begin
  FBorderSize := Value;
  Invalidate;
end;

{ TIWOutlookItems }

function TIWOutlookItems.Add: TIWOutlookItem;
begin
  Result := TIWOutlookItem(inherited Add);
  TIWOutlookPanels(FOwner.GetOwner).FOwner.Invalidate;
end;

constructor TIWOutlookItems.Create(AOwner: TIWOutlookPanel);
begin
  inherited Create(AOwner, CreateItemClass);
  FOwner := AOwner;
end;

function TIWOutlookItems.CreateItemClass: TCollectionItemClass;
begin
  Result := TIWOutlookItem;
end;

function TIWOutlookItems.GetItem(Index: integer): TIWOutlookItem;
begin
  Result := TIWOutlookItem(inherited Items[Index]);
end;

function TIWOutlookItems.Insert(index: integer): TIWOutlookItem;
begin
  Result := TIWOutlookItem(inherited Insert(Index));
  TIWOutlookPanels(FOwner.GetOwner).FOwner.Invalidate;
end;

procedure TIWOutlookItems.SetItem(Index: integer;
  const Value: TIWOutlookItem);
begin
  inherited Items[Index] := Value;
end;

procedure TIWOutlookItems.Update(Item: TCollectionItem);
begin
  if Assigned(Item) then
    TIWOutlookPanels(FOwner.GetOwner).FOwner.InvalidateItem(FOwner, TIWOutlookItem(Item))
  else
    TIWOutlookPanels(FOwner.GetOwner).FOwner.Invalidate;
end;

{ TIWOutlookPanel }

constructor TIWOutlookPanel.Create(Collection: TCollection);
begin
  inherited;
  FItems := CreateItems;
  FScript := '';
  FImageIndex := -1;
end;

function TIWOutlookPanel.CreateItems: TIWOutlookItems;
begin
  Result := TIWOutlookItems.Create(Self);
end;

destructor TIWOutlookPanel.Destroy;
begin
  FItems.Free;
  inherited;
end;

function TIWOutlookPanel.GetDisplayName: string;
begin
  if Caption <> '' then
    Result := Caption
  else
    Result := 'TIWOutlookPanel' + IntToStr(Index);
end;

function TIWOutlookPanel.GetOutlookBar: TTIWOutlookBar;
begin
  Result := TIWOutlookPanels(Collection).FOwner;
end;

procedure TIWOutlookPanel.SetCaption(const Value: string);
begin
  FCaption := Value;
  Changed(False);
end;

procedure TIWOutlookPanel.SetImageIndex(const Value: integer);
begin
  FImageIndex := Value;
  Changed(False);
end;

procedure TIWOutlookPanel.SetScript(const Value : string);
begin
  FScript := Value;
end;

procedure TIWOutlookPanel.Assign(Source: TPersistent);
begin
  Caption := (Source as TIWOutlookPanel).Caption;
  ImageIndex := (Source as TIWOutlookPanel).ImageIndex;
  Tag := (Source as TIWOutlookPanel).Tag;
  Items.Assign((Source as TIWOutlookPanel).Items);
end;

procedure TIWOutlookPanel.SetOutlookItems(const Value: TIWOutlookItems);
begin
  FItems.Assign(Value);
  Changed(False);
end;

{ TIWOutlookItem }

procedure TIWOutlookItem.Changed;
begin
  TIWOutlookItems(GetOwner).Update(Self);
end;

constructor TIWOutlookItem.Create(Collection: TCollection);
begin
  inherited;
  FBitmap := nil;
  FImageIndex := -1;
end;

destructor TIWOutlookItem.Destroy;
begin
  if FBitmap <> nil then
    FBitmap.Free;
  inherited;
end;

function TIWOutlookItem.GetBitmap: TBitmap;
begin
  if FBitmap = nil then
    FBitmap := TBitmap.Create;
  Result := FBitmap;
end;


procedure TIWOutlookItem.Assign(Source: TPersistent);
begin
  Bitmap.Assign((Source as TIWOutlookItem).Bitmap);
  Caption := (Source as TIWOutlookItem).Caption;
  Hint := (Source as TIWOutlookItem).Hint;
  ImageIndex := (Source as TIWOutlookItem).ImageIndex;
  Tag := (Source as TIWOutlookItem).Tag;
end;


function TIWOutlookItem.GetDisplayName: string;
begin
  if Caption <> '' then
    Result := Caption
  else
    Result := 'TIWOutlookItem' + IntToStr(Index);
end;

function TIWOutlookItem.GetOutlookBar: TTIWOutlookBar;
begin
  Result := TIWOutlookPanels(TIWOutlookItems(Collection).FOwner.Collection).FOwner;
end;

function TIWOutlookItem.GetOutlookPanel: TIWOutlookPanel;
begin
  Result := TIWOutlookItems(Collection).FOwner;
end;

procedure TIWOutlookItem.SetBitmap(const Value: TBitmap);
begin
  if Value = nil then
  begin
    if FBitmap <> nil then
    begin
      FBitmap.Free;
      FBitmap := nil;
    end
  end
  else
  begin
    if FBitmap = nil then
      FBitmap := TBitmap.Create;
    FBitmap.Assign(Value);
  end;
  Changed;
end;

procedure TIWOutlookItem.SetCaption(const Value: string);
begin
  FCaption := Value;
  Changed;
end;

procedure TIWOutlookItem.SetImageIndex(const Value: integer);
begin
  FImageIndex := Value;
  Changed;
end;

procedure TIWOutlookItem.SetScript(const Value : string);
begin
  FScript := Value;
end;

procedure TIWOutlookItem.SetLink(const Value :string);
begin
  FLink := Value;
end;

{ TIWOutlookPanels }

function TIWOutlookPanels.Add: TIWOutlookPanel;
begin
  Result := TIWOutlookPanel(inherited Add);
end;

constructor TIWOutlookPanels.Create(AOwner: TTIWOutlookBar);
begin
  inherited Create(AOwner, CreateItemClass);
  FOwner := AOwner;
end;

function TIWOutlookPanels.CreateItemClass: TCollectionItemClass;
begin
  Result := TIWOutlookPanel;
end;

function TIWOutlookPanels.GetItem(Index: integer): TIWOutlookPanel;
begin
  Result := TIWOutlookPanel(inherited Items[Index]);
end;

function TIWOutlookPanels.Insert(index: integer): TIWOutlookPanel;
begin
  Result := TIWOutlookPanel(inherited Insert(Index));
end;

procedure TIWOutlookPanels.SetItem(Index: integer;
  const Value: TIWOutlookPanel);
begin
  inherited Items[Index] := Value;
end;

procedure TIWOutlookPanels.Update(Item: TCollectionItem);
begin
  inherited;
  FOwner.Invalidate;
end;

end.