{***************************************************************************}
{ TMS Smooth TimeLine for IntraWeb                                          }
{ for Delphi & C++Builder                                                   }
{                                                                           }
{ written by TMS Software                                                   }
{            copyright © 2008 - 2015                                        }
{            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 iwTimeLine;

{$I TMSDEFS.INC}

interface

uses
  IWAdvSmoothTimeLine, IWGDIPFill, IWAdvSmoothGDIP, IWAdvStyleIF, IWApplication,
  Controls, Graphics, Windows,
  {$IFDEF DELPHI6_LVL}
  Types,
  {$ENDIF}
  Classes, IWControl, IWTypes, SysUtils, JPEG, IWHTMLTag, IWTMSBase,
  IWRenderContext, IWColor, IWXMLTag
  {$IFDEF TMSIW121}
  ,IWCompExtCtrls
  {$ELSE}
  ,IWExtCtrls
  {$ENDIF}
  ;

const
  MAJ_VER = 1; // Major version nr.
  MIN_VER = 1; // Minor version nr.
  REL_VER = 0; // Release nr.
  BLD_VER = 3; // Build nr.
  DATE_VER = 'JAN, 2015'; // Month version

  //v1.0.0.1 : Fixed: Issue with transparency when rendering images
  //v1.0.0.2 : Fixed: Issue with assigning Tag property
  //v1.0.0.3 : Fixed: Issue with async events

type
  TTIWSmoothTimeLine = class;

  TTIWSmoothTimeLineAppearance = class(TPersistent)
  private
    FDefaultIndicators: TIWAdvSmoothTimeLineBarIndicators;
    FIWOwner: TTIWSmoothTimeLine;
    FTimeLineIndicators: TIWAdvSmoothTimeLineBarIndicators;
    FRangeAppearance: TIWAdvSmoothTimeLineRangeAppearance;
    FVerticalMargin: integer;
    FDefaultIndicator: TIWAdvSmoothTimeLineBarIndicator;
    FTimeLineBar: TIWAdvSmoothTimeLineBar;
    FTimeLineBarSections: TIWAdvSmoothTimeLineBarSections;
    FFill: TIWGDIPFill;
    FHorizontalMargin: integer;
    FDefaultSectionFill: TIWGDIPFill;
    FRange: TIWAdvSmoothTimeLineRange;
    procedure SetDefaultIndicator(
      const Value: TIWAdvSmoothTimeLineBarIndicator);
    procedure SetDefaultSectionFill(const Value: TIWGDIPFill);
    procedure SetFill(const Value: TIWGDIPFill);
    procedure SetHorizontalMargin(const Value: integer);
    procedure SetRange(const Value: TIWAdvSmoothTimeLineRange);
    procedure SetRangeAppearance(
      const Value: TIWAdvSmoothTimeLineRangeAppearance);
    procedure SetTimeLineBar(const Value: TIWAdvSmoothTimeLineBar);
    procedure SetTimeLineBarSections(
      const Value: TIWAdvSmoothTimeLineBarSections);
    procedure SetTimeLineIndicators(
      const Value: TIWAdvSmoothTimeLineBarIndicators);
    procedure SetVerticalMargin(const Value: integer);
  protected
    procedure Changed;
    procedure ObjectChanged(Sender: TObject);
  public
    constructor Create(IWOwner: TTIWSmoothTimeLine; AOwner: TIWAdvSmoothTimeLine);
    destructor Destroy; override;
    property TimeLineSections: TIWAdvSmoothTimeLineBarSections read FTimeLineBarSections write SetTimeLineBarSections;
    property TimeLineIndicators: TIWAdvSmoothTimeLineBarIndicators read FTimeLineIndicators write SetTimeLineIndicators;
  published
    property DefaultSectionFill: TIWGDIPFill read FDefaultSectionFill write SetDefaultSectionFill;
    property DefaultIndicator: TIWAdvSmoothTimeLineBarIndicator read FDefaultIndicator write SetDefaultIndicator;
    property Range: TIWAdvSmoothTimeLineRange read FRange write SetRange;
    property RangeAppearance: TIWAdvSmoothTimeLineRangeAppearance read FRangeAppearance write SetRangeAppearance;
    property Fill: TIWGDIPFill read FFill write SetFill;
    property VerticalMargin: integer read FVerticalMargin write SetVerticalMargin default 10;
    property HorizontalMargin: integer read FHorizontalMargin write SetHorizontalMargin default 25;
    property TimeLineBar: TIWAdvSmoothTimeLineBar read FTimeLineBar write SetTimeLineBar;
  end;

  TTIWSmoothTimeLine = class(TIWControl, ITMSStyle)
  private
    FItemClicked: Boolean;
    FTimeLineClicked: Boolean;
    FTimeLineClickPosition: TDateTime;
    FTimeLineClickSection: TIWAdvSmoothTimeLineBarSection;
    FTimeLineClickIndicator: TIWAdvSmoothTimeLineBarIndicator;
    FNoResize: Boolean;
    FVersion: string;
    FChanged: boolean;
    FUpdateCount: integer;
    FTimeLine: TIWAdvSmoothTimeLine;
    FImageType: TImageType;
    FImageQuality: Integer;
    FAppearance: TTIWSmoothTimeLineAppearance;
    FOnSectionClick: TIWAdvSmoothTimeLineSectionClick;
    FOnIndicatorClick: TIWAdvSmoothTimeLineIndicatorClick;
    FOnTimeLineClick: TIWAdvSmoothTimeLineClick;
    FOnAsyncSectionClick: TIWAdvSmoothTimeLineSectionClick;
    FOnAsyncIndicatorClick: TIWAdvSmoothTimeLineIndicatorClick;
    FOnAsyncTimeLineClick: TIWAdvSmoothTimeLineClick;

    function GetVersion: string;
    function OutputImage: string;
    procedure SetImageType(const Value: TImageType);
    procedure SetImageQuality(const Value: Integer);
    procedure SetAppearance(const Value: TTIWSmoothTimeLineAppearance);
  protected
    function ImageHTML(const ASrc,BSrc: string; AContext: TIWBaseComponentContext): TIWHTMLTag;
    procedure SetValue(const value:string); override;
    procedure DoIndicatorClick(Sender: TObject; indicator: TIWAdvSmoothTimeLineBarIndicator);
    procedure DoSectionClick(Sender: TObject; section: TIWAdvSmoothTimeLineBarSection);
    procedure DoTimeLineClick(Sender: TObject; Position: TDateTime);
    procedure DoAsyncTimeLineClick(AParams: TStringList);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure TimeLineChanged(Sender: TObject);
    procedure ApplyAppearance;
    procedure IWPaint; override;
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    function RenderAsync(AContext: TIWBaseHTMLComponentContext): TIWXMLTag; override;
    function GetVersionNr: Integer; virtual;
    function GetVersionString: string; virtual;
    procedure Resize; override;
    procedure SetComponentStyle(AStyle: TTMSStyle);
  published
    property Appearance: TTIWSmoothTimeLineAppearance read FAppearance write SetAppearance;
    property Version: string read GetVersion;
    property ImageType: TImageType read FImageType write SetImageType default itPng;
    property ImageQuality: Integer read FImageQuality write SetImageQuality default 100;
    property OnIndicatorClick: TIWAdvSmoothTimeLineIndicatorClick read FOnIndicatorClick write FOnIndicatorClick;
    property OnSectionClick: TIWAdvSmoothTimeLineSectionClick read FOnSectionClick write FOnSectionClick;
    property OnClick: TIWAdvSmoothTimeLineClick read FOnTimeLineClick write FOnTimeLineClick;
    property OnAsyncIndicatorClick: TIWAdvSmoothTimeLineIndicatorClick read FOnAsyncIndicatorClick write FOnAsyncIndicatorClick;
    property OnAsyncSectionClick: TIWAdvSmoothTimeLineSectionClick read FOnAsyncSectionClick write FOnAsyncSectionClick;
    property OnAsyncClick: TIWAdvSmoothTimeLineClick read FOnAsyncTimeLineClick write FOnAsyncTimeLineClick;
  end;

  function GetControlHTML(Control: TIWCustomControl; AContext: TIWBaseComponentContext): string;

implementation

uses
  IWGlobal, IWAppForm, IWForm, IWServerControllerBase,
  TMSIWStrings, TMSIWSystem;

function GetControlHTML(Control: TIWCustomControl;
  AContext: TIWBaseComponentContext): string;
var
  it: TIWHTMLTag;
begin
  // !!!!!!!!!!!!!! IMPORTANT NOTICE !!!!!!!!!!!!!!!!!!
  //
  // If you encounter a compilation problem here,
  // make sure that you followed the installation steps
  // in INSTALL.TXT, in particular, that you're using the
  // correct TMSDEFS.INC file
  //
  // !!!!!!!!!!!!!! IMPORTANT NOTICE !!!!!!!!!!!!!!!!!!

  it := Control.RenderHTML(AContext);
  Result := it.Render;
  it.Free;
end;


{ TTIWAdvChart }

function TTIWSmoothTimeLine.RenderAsync(
  AContext: TIWBaseHTMLComponentContext): TIWXMLTag;
var
  js, ImgName: string;
begin
  Result := TIWXMLTag.CreateTag('control');
  try
    Result.AddStringParam('id', HTMLName);
    Result.AddStringParam('type', 'TTIWSmoothTimeLine');
    RenderAsyncCommonProperties( AContext, Result );

    ImgName := OutputImage;

    js :=
      '<![CDATA['
      + 'document.getElementById("' + HTMLName + '_IMG").src = "' + GetCacheDir + ExtractFileName(ImgName) + '"'#13
      +']]>';

    GGetWebApplicationThreadVar.CallBackResponse.AddJavaScriptToExecute(js);

  except
    FreeAndNil(Result);
  end;
end;

function TTIWSmoothTimeLine.GetVersion: string;
begin
  Result := FVersion;
end;

function TTIWSmoothTimeLine.GetVersionNr: Integer;
begin
  Result := MakeLong(MakeWord(BLD_VER, REL_VER), MakeWord(MIN_VER, MAJ_VER));
end;

function TTIWSmoothTimeLine.GetVersionString: string;
var
  vn: Integer;
begin
  vn := GetVersionNr;
  Result := IntToStr(Hi(Hiword(vn))) + '.' + IntToStr(Lo(Hiword(vn))) + '.' + IntToStr(Hi(Loword(vn))) + '.' + IntToStr(Lo(Loword(vn))) + ' ' + DATE_VER;
end;

procedure TTIWSmoothTimeLine.ApplyAppearance;
var
  I: Integer;
begin
  FTimeLine.BeginUpdate;
  FTimeLine.Width := Width;
  FTimeLine.Height := Height;
  FTimeLine.DefaultSectionFill.Assign(Appearance.DefaultSectionFill);
  FTimeLine.DefaultIndicator.Assign(Appearance.DefaultIndicator);
  FTimeLine.Range.Assign(Appearance.Range);
  FtimeLine.RangeAppearance.Assign(Appearance.RangeAppearance);
  FTimeLine.Fill.Assign(Appearance.Fill);
  FTimeLine.VerticalMargin := Appearance.VerticalMargin;
  FTimeLine.HorizontalMargin := Appearance.HorizontalMargin;
  FTimeLine.TimeLineBar.Assign(Appearance.TimeLineBar);
  FTimeLine.TimeLineSections.Assign(Appearance.TimeLineSections);
  FTimeLine.TimeLineIndicators.Assign(Appearance.TimeLineIndicators);
  for I := 0 to Appearance.TimeLineIndicators.Count - 1 do
    FTimeLine.TimeLineIndicators[I].Position := Appearance.TimeLineIndicators[I].Position;

  FTimeLine.EndUpdate;
end;

constructor TTIWSmoothTimeLine.Create(AOwner: TComponent);
begin
  inherited;
  FTimeLine := TIWAdvSmoothTimeLine.Create(Self);
  FTimeLine.OnChange := TimeLineChanged;
  FTimeLine.TabStop := false;
  FTimeLine.OnIndicatorClick := DoIndicatorClick;
  FTimeLine.OnSectionClick := DoSectionClick;
  FTimeLine.OnTimeLineClick := DoTimeLineClick;
  FAppearance := TTIWSmoothTimeLineAppearance.Create(Self, FTimeLine);
  if (csDesigning in ComponentState) and not
    ((csReading in Owner.ComponentState) or (csLoading in Owner.ComponentState)) then
      SetComponentStyle(tsOffice2007Luna);

  FImageType := itPng;
  FImageQuality := 100;

  FNoResize := true;
  Width := FTimeLine.Width;
  Height := FTimeLine.Height;
  FNoResize := false;
  FUpdateCount := 0;
  FVersion := GetVersionString;
end;

destructor TTIWSmoothTimeLine.Destroy;
begin
  FAppearance.Free;
  FTimeLine.Free;
  inherited;
end;

procedure TTIWSmoothTimeLine.DoAsyncTimeLineClick(AParams: TStringList);
begin
    if FTimeLineClickIndicator <> nil then
    begin
      if Assigned(OnAsyncIndicatorClick) then
        OnAsyncIndicatorClick(self, FTimeLineClickIndicator);
      FTimeLineClickIndicator := nil;
    end
    else if FTimeLineClickSection <> nil then
    begin
      if Assigned(OnAsyncSectionClick) then
        OnAsyncSectionClick(self, FTimeLineClickSection);
      FTimeLineClickSection := nil;
    end
    else if FTimeLineClicked then
    begin
      if Assigned(OnAsyncClick) then
        OnAsyncClick(self, FTimeLineClickPosition);
      FTimeLineClicked := false;
    end;
end;

procedure TTIWSmoothTimeLine.DoIndicatorClick(Sender: TObject;
  indicator: TIWAdvSmoothTimeLineBarIndicator);
begin
  FItemClicked := true;
  FTimeLineClickIndicator := indicator;
  FTimeLineClicked := false;

//  OutputDebugString(pchar('indicator clicked' + indicator.Annotation));

  if Assigned(OnIndicatorClick) then
    OnIndicatorClick(Sender, indicator);
end;

procedure TTIWSmoothTimeLine.DoSectionClick(Sender: TObject;
  section: TIWAdvSmoothTimeLineBarSection);
begin
  FItemClicked := true;
  FTimeLineClickSection := section;
  FTimeLineClicked := false;

//  OutputDebugString(pchar('section clicked' + section.Caption));

  if Assigned(OnSectionClick) then
    OnSectionClick(Sender, section);
end;

procedure TTIWSmoothTimeLine.DoTimeLineClick(Sender: TObject; Position: TDateTime);
begin
  if not FItemClicked then
  begin
    FTimeLineClicked := true;
    FTimeLineClickPosition := Position;

//    OutputDebugString(pchar('timeline clicked' + DateToStr(Position)));    

    if Assigned(OnClick) then
      OnClick(Sender, Position);
  end;
end;

procedure TTIWSmoothTimeLine.IWPaint;
begin
  if not (Assigned(FTimeLine)) then
  begin
    inherited;
    Exit;
  end;

  inc(FUpdateCount);

  if FChanged then
  begin
    ApplyAppearance;
  end;

  FChanged := false;

  // design time painting
  FTimeLine.DrawTimeLine(Canvas);

  dec(FUpdateCount);
end;

function TTIWSmoothTimeLine.ImageHTML(const ASrc, BSrc: string; AContext: TIWBaseComponentContext): TIWHTMLTag;
var
  sl: TStringList;
begin
  Result := TIWHTMLTag.CreateTag('DIV');
  sl := TStringList.Create;
  with sl do
  begin
    Add('<Script Language="JavaScript">');
    Add('function '+HTMLName+'DoMouseEvent(e, el, act)');
    Add('{');
//    Add('var isIE = navigator.appName.indexOf("Microsoft") != -1;');
    if IsBrowserIE(AContext) then
      Add('var isIE = true;')
    else
      Add('var isIE = false;');
    Add('var x;');
    Add('var y;');
    Add('var cx;');
    Add('var cy;');
    Add('if (isIE)');
    Add('{');
    Add('x = event.clientX;');
    Add('y = event.clientY;');
    Add('}');
    Add('else');
    Add('{');
    Add('x = e.clientX;');
    Add('y = e.clientY;');
    Add('}');
    Add('x = x - '+inttostr(Left));
    Add('y = y - '+inttostr(Top));


//    Add('if (document.compatMode && document.compatMode != "BackCompat")');
    Add('if (isIE)');
    Add('{');
    Add('  x = x + document.documentElement.scrollLeft;');
    Add('  y = y + document.documentElement.scrollTop;');
    Add('}');
    Add('else');
    Add('{');
    Add('  x = x + document.body.scrollLeft;');
    Add('  y = y + document.body.scrollTop;');
    Add('}');

    Add(
      '  var parentLeft = 0;'
      + '  var parentTop = 0;'

      + '  var elParent = el.offsetParent;'
      + '  while (( elParent = elParent.offsetParent)) {'
      + '    parentLeft += elParent.offsetLeft;'
      + '    parentTop += elParent.offsetTop;'
      + '  }'
      + '  x = x - parentLeft;'
      + '  y = y - parentTop;'
      );

    Add(' FindElem(''' + HTMLName + '_INPUT'').value = ""+act+"@"+x+";"+y');

    if Assigned(OnClick) or Assigned(OnIndicatorClick) or Assigned(OnSectionClick) then
      Add('return SubmitClick('#39+HTMLName+#39', 0, '#39'false'#39');'#13)
    else
      Add('processAjaxEvent(''onTimeLineClick'', '
        + HTMLControlImplementation.IWCLName
        + ',''' + HTMLName + '.' + 'DoAsyncTimeLineClick' + ''','
        + 'true' + ', null, '
        + 'true' + ');');

    //Fix: prevent multiple postbacks with same value if
    //the event would get called twice.
    //(in combination with TIWAdvMessageDialog)
    Add(' FindElem(''' + HTMLName + '_INPUT'').value = ""');

    Add('}');
    Add('</script>');
  end;
  Result.Contents.AddText(sl.Text);
  sl.Free;
  with Result.Contents.AddTag('IMG') do
  begin
    AddStringParam('SRC', ASrc);
    AddStringParam('NAME', HTMLName);
    AddStringParam('ID', HTMLName+'_IMG');
    AddIntegerParam('WIDTH', Width);
    AddIntegerParam('HEIGHT', Height);
    AddStringParam('OnMouseUp',  HTMLName+'DoMouseEvent(event, this, ''u'')');
  end;
  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName+'');
    AddStringParam('ID',HTMLName+'_INPUT');
  end;
end;

function TTIWSmoothTimeLine.OutputImage: string;
var
  ImgName, str: string;
  {$IFDEF TMSIW14}
  ms: TMemoryStream;
  imgType: TIWImageType;
  {$ENDIF}
begin
  ImgName := '';

  if Assigned(FTimeLine) then
  begin
    case ImageType of
      itPNG: str := 'png';
      itBMP: str := 'bmp';
      itJPEG: str := 'jpg';
      itTIFF: str := 'tiff';
      itGIF: str := 'gif';
    end;
    {$IFNDEF TMSIW14}
    ImgName := GetNewCacheFile(str,true);
    {$ENDIF}

    ApplyAppearance;

    {$IFNDEF TMSIW14}
    FTimeLine.SaveToImage(ImgName, Width, Height, ImageType, ImageQuality);
    {$ENDIF}

    {$IFDEF TMSIW14}
    ms := TMemoryStream.Create;

    try
      FTimeLine.SaveToStream(ms, Width, Height, ImageType, ImageQuality);
      ms.Position := 0;

      case ImageType of
      itPNG: imgtype := imgPNG;
      itBMP: imgtype := imgBMP;
      itJPEG: imgtype := imgJPEG;
      itGIF: imgtype := imgGIF;
      else
        imgtype := imgPNG;
      end;

      ImgName := TIWAppCache.StreamToCacheFile(ms, imgtype);
    finally
      ms.Free;
    end;
    {$ENDIF}

  end;

  Result := ImgName;
end;

procedure TTIWSmoothTimeLine.TimeLineChanged(Sender: TObject);
begin
  if FUpdateCount = 0 then
  begin
    FChanged := true;
    Invalidate;
  end;
end;

function TTIWSmoothTimeLine.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
var
  ImgName,ImgHot: string;
  htmlres: string;
begin
  htmlres := '';
  ImgName := '';
  ImgHot := '';

  //Register async refresh
  AContext.WebApplication.RegisterCallBack(HTMLName + '.DoAsyncTimeLineClick', DoAsyncTimeLineClick);

  ImgName := OutputImage;

  Result := ImageHTML(GetCacheDir + ExtractFilename(ImgName),
  GetCacheDir + ExtractFilename(ImgHot), AContext);
end;

procedure TTIWSmoothTimeLine.Resize;
begin
  inherited;
  if Assigned(FTimeLine) and not FNoResize then
  begin
    FTimeLine.Width := Width;
    FTimeLine.Height := Height;
    FChanged := true;
  end;
end;

procedure TTIWSmoothTimeLine.SetAppearance(
  const Value: TTIWSmoothTimeLineAppearance);
begin
  if FAppearance <> value then
  begin
    FAppearance.Assign(Value);
    TimeLineChanged(Self);
  end;
end;

procedure TTIWSmoothTimeLine.SetComponentStyle(AStyle: TTMSStyle);
var
  I: Integer;
begin
  with Appearance do
  begin
  RangeAppearance.DivisionFont.Color := clBlack;
  RangeAppearance.subDivisionFont.Color := clBlack;
  RangeAppearance.DivisionTickMarkColor := clBlack;
  RangeAppearance.SubDivisionTickMarkColor := clBlack;


   case AStyle of
      tsOffice2003Blue:
        begin
          Fill.Color := $00FFD2AF;
          Fill.ColorTo := $00FFD2AF;
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := $D68759;
          TimeLineBar.Fill.ColorTo := $933803;
          TimeLineBar.Fill.Color := clWhite;
          TimeLineBar.Fill.BorderColor := $962D00;

          DefaultSectionFill.Color := $AAD9FF;
          DefaultSectionFill.ColorTo := $6EBBFF;
          DefaultSectionFill.ColorMirror := $42AEFE;
          DefaultSectionFill.ColorMirrorTo := $7AE1FE;
          DefaultSectionFill.BorderColor := $42AEFE;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
      tsOffice2003Silver:
        begin
          Fill.Color := $00E6D8D8;
          Fill.ColorTo := $00E6D8D8;
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := $BDA4A5;
          TimeLineBar.Fill.ColorTo := $957475;
          TimeLineBar.Fill.BorderColor := $947C7C;

          DefaultSectionFill.Color := $AAD9FF;
          DefaultSectionFill.ColorTo := $6EBBFF;
          DefaultSectionFill.ColorMirror := $42AEFE;
          DefaultSectionFill.ColorMirrorTo := $7AE1FE;
          DefaultSectionFill.BorderColor := $42AEFE;
          DefaultSectionFill.GradientMirrorType := gtVertical;

        end;
      tsOffice2003Olive:
        begin
          Fill.Color := RGB(225, 234, 185);
          Fill.ColorTo := RGB(225, 234, 185);
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := $82C0AF;
          TimeLineBar.Fill.ColorTo := $447A63;
          TimeLineBar.Fill.BorderColor := $588060;

          DefaultSectionFill.Color := $AAD9FF;
          DefaultSectionFill.ColorTo := $6EBBFF;
          DefaultSectionFill.ColorMirror := $42AEFE;
          DefaultSectionFill.ColorMirrorTo := $7AE1FE;
          DefaultSectionFill.BorderColor := $42AEFE;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
      tsOffice2003Classic:
        begin
          Fill.Color := $00F2F2F2;
          Fill.ColorTo := $00F2F2F2;
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := $808080;
          TimeLineBar.Fill.ColorTo := $808080;
          TimeLineBar.Fill.BorderColor := $808080;

          DefaultSectionFill.Color := $B59285;
          DefaultSectionFill.ColorTo := $B59285;
          DefaultSectionFill.ColorMirror := clNone;
          DefaultSectionFill.ColorMirrorTo := clNone;
          DefaultSectionFill.BorderColor := $808080;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
      tsOffice2007Luna:
        begin
          Fill.Color := $00F3E5DA;
          Fill.ColorTo := $00F0DED0;
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := $FFEFE3;
          TimeLineBar.Fill.ColorTo := $FFD2AF;
          TimeLineBar.Fill.BorderColor := $00FFD2AF;

          DefaultSectionFill.Color := $AAD9FF;
          DefaultSectionFill.ColorTo := $6EBBFF;
          DefaultSectionFill.ColorMirror := $42AEFE;
          DefaultSectionFill.ColorMirrorTo := $7AE1FE;
          DefaultSectionFill.BorderColor := $42AEFE;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
      tsOffice2007Obsidian:
        begin
          Fill.Color := $5C534C;
          Fill.ColorTo := $5C534C;
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := $F2F1F0;
          TimeLineBar.Fill.ColorTo := $C9C2BD;
          TimeLineBar.Fill.BorderColor := $5C534C;

          DefaultSectionFill.Color := $AAD9FF;
          DefaultSectionFill.ColorTo := $6EBBFF;
          DefaultSectionFill.ColorMirror := $42AEFE;
          DefaultSectionFill.ColorMirrorTo := $7AE1FE;
          DefaultSectionFill.BorderColor := $42AEFE;
          DefaultSectionFill.GradientMirrorType := gtVertical;

          RangeAppearance.DivisionFont.Color := clWhite;
          RangeAppearance.subDivisionFont.Color := clWhite;
          RangeAppearance.DivisionTickMarkColor := clWhite;
          RangeAppearance.SubDivisionTickMarkColor := clWhite;
        end;
      tsWindowsXP:
        begin
          Fill.Color := $00B6B6B6;
          Fill.ColorTo := $00B6B6B6;

          TimeLineBar.Fill.Color := clBtnFace;
          TimeLineBar.Fill.ColorTo := clBtnFace;
          TimeLineBar.Fill.BorderColor := clBlack;

          DefaultSectionFill.Color := clInactiveCaption;
          DefaultSectionFill.ColorTo := clInactiveCaption;
          DefaultSectionFill.ColorMirror := clNone;
          DefaultSectionFill.ColorMirrorTo := clNone;
          DefaultSectionFill.BorderColor := clHighLight;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
      tsWhidbey:
        begin
          Fill.Color := $F5F9FA;
          Fill.ColorTo := $F5F9FA;
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := $EBEEEF;
          TimeLineBar.Fill.ColorTo := $7E9898;
          TimeLineBar.Fill.BorderColor := $962D00;

          DefaultSectionFill.Color := $AAD9FF;
          DefaultSectionFill.ColorTo := $6EBBFF;
          DefaultSectionFill.ColorMirror := $42AEFE;
          DefaultSectionFill.ColorMirrorTo := $7AE1FE;
          DefaultSectionFill.BorderColor := $42AEFE;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
      tsCustom: ;
      tsOffice2007Silver:
        begin
          Fill.Color := RGB(241, 244, 248);
          Fill.ColorTo := RGB(227, 232, 240);
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := $F8F7F6;
          TimeLineBar.Fill.ColorTo := $E8E0DB;
          TimeLineBar.Fill.BorderColor := $74706F;

          DefaultSectionFill.Color := $AAD9FF;
          DefaultSectionFill.ColorTo := $6EBBFF;
          DefaultSectionFill.ColorMirror := $42AEFE;
          DefaultSectionFill.ColorMirrorTo := $7AE1FE;
          DefaultSectionFill.BorderColor := $42AEFE;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
        tsWindowsVista:
        begin
          Fill.Color := $FFFDF9;
          Fill.ColorTo := $FFFAF0;
          Fill.BorderColor := $FCF2DA;

          TimeLineBar.Fill.Color := $FEF9F0;
          TimeLineBar.Fill.ColorTo := $FDF0D7;
          TimeLineBar.Fill.BorderColor := $FEDF9A;

          DefaultSectionFill.Color := $FCEBDC;
          DefaultSectionFill.ColorTo := $FCDBC1;
          DefaultSectionFill.ColorMirror := clNone;
          DefaultSectionFill.ColorMirrorTo := clNone;
          DefaultSectionFill.BorderColor := $CEA27D;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
        tsWindows7:
        begin
          Fill.Color := $FCEBDC;
          Fill.ColorTo := $FCDBC1;
          Fill.BorderColor := $CEA27D;

          TimeLineBar.Fill.Color := $FEF9F0;
          TimeLineBar.Fill.ColorTo := $FDF0D7;
          TimeLineBar.Fill.BorderColor := $FEDF9A;

          DefaultSectionFill.Color := $FCEBDC;
          DefaultSectionFill.ColorTo := $FCDBC1;
          DefaultSectionFill.ColorMirror := clNone;
          DefaultSectionFill.ColorMirrorTo := clNone;
          DefaultSectionFill.BorderColor := $CEA27D;
          DefaultSectionFill.GradientMirrorType := gtVertical;
        end;
        tsTerminal:
        begin
          Fill.Color := clBtnFace;
          Fill.ColorTo := clBtnFace;
          Fill.BorderColor := clNone;

          TimeLineBar.Fill.Color := clSilver;
          TimeLineBar.Fill.ColorTo := clSilver;
          TimeLineBar.Fill.BorderColor := clGray;

          DefaultSectionFill.Color := clHighLight;
          DefaultSectionFill.ColorTo := clHighLight;
          DefaultSectionFill.ColorMirror := clNone;
          DefaultSectionFill.ColorMirrorTo := clNone;
          DefaultSectionFill.BorderColor := clGray;

        end;
    end;

    DefaultIndicator.Color := DefaultSectionFill.Color;
    DefaultIndicator.ColorTo := DefaultSectionFill.ColorTo;
    DefaultIndicator.OpacityTo := 150;
    DefaultIndicator.Opacity := 200;
    DefaultIndicator.AnnotationColor := DefaultSectionFill.ColorTo;

    Fill.BorderColor := clSilver;

    for I := 0 to TimeLineSections.Count - 1 do
      TimeLineSections[I].Fill.Assign(DefaultSectionFill);

    for I := 0 to TimeLineIndicators.Count - 1 do
      TimeLineIndicators[I].AssignVisuals(DefaultIndicator);
  end;
end;

procedure TTIWSmoothTimeLine.SetImageQuality(const Value: Integer);
begin
  if fImageQuality <> value then
  begin
    FImageQuality := Value;
    TimeLineChanged(Self);
  end;
end;

procedure TTIWSmoothTimeLine.SetImageType(const Value: TImageType);
begin
  if FImageType <> value then
  begin
    FImageType := Value;
    TimeLineChanged(Self);
  end;
end;

procedure TTIWSmoothTimeLine.SetValue(const value: string);
var
  vp, x, y: Integer;
  varvalue, m: string;
begin
  varvalue := value;

  if Length(value) > 0 then
  begin
    vp := Pos(';', varvalue);

    if vp > 0 then
    begin
      m := Copy(varvalue, 0, Pos('@', varvalue) - 1);
      x := strtoint(Copy(varvalue, Pos('@', varvalue) + 1, Pos(';', varvalue) - Pos('@', varvalue) - 1));
      y := strtoint(Copy(varvalue, Pos(';', varvalue) + 1 , Length(varvalue) - Pos(';', varvalue)));

//      OutputDebugString(pchar('### values: x= ' + IntToStr(x) + ' y=' + IntToStr(y)));

      if Assigned(FTimeLine) then
      begin
        FItemClicked := false;
        FTimeLine.DoMouseClick(mbLeft, [], X, Y);
      end;

      inherited SetValue(varvalue);
    end;
  end
end;

{ TTIWSmoothTimeLineAppearance }

procedure TTIWSmoothTimeLineAppearance.Changed;
begin
  FIWOwner.TimeLineChanged(Self);
end;

constructor TTIWSmoothTimeLineAppearance.Create(IWOwner: TTIWSmoothTimeLine;
  AOwner: TIWAdvSmoothTimeLine);
begin
  FIWOwner := IWOwner;
  FRange := TIWAdvSmoothTimeLineRange.Create(AOwner);
  FRange.OnChange := ObjectChanged;
  FRangeAppearance := TIWAdvSmoothTimeLineRangeAppearance.Create(AOwner);
  FRangeAppearance.OnChange := ObjectChanged;
  FFill := TIWGDIPFill.Create;
  FFill.OnChange := ObjectChanged;
  FVerticalMargin := 10;
  FHorizontalMargin := 25;
  FTimeLineBar := TIWAdvSmoothTimeLineBar.Create(AOwner);
  FTimeLineBar.OnChange := ObjectChanged;
  FTimeLineBarSections := TIWAdvSmoothTimeLineBarSections.Create(AOwner);
  FTimeLinebarSections.OnChange := ObjectChanged;
  FDefaultSectionFill := TIWGDIPFill.Create;
  FTimeLineIndicators := TIWAdvSmoothTimeLineBarIndicators.Create(AOwner);
  FTimeLineIndicators.OnChange := ObjectChanged;
  FDefaultIndicators := TIWAdvSmoothTimeLineBarIndicators.Create(AOwner);
  FDefaultIndicator := FDefaultIndicators.Add;
end;

destructor TTIWSmoothTimeLineAppearance.Destroy;
begin
  FDefaultIndicator.Free;
  FDefaultIndicator := nil;
  FDefaultIndicators.Free;
  FRange.Free;
  FRangeAppearance.Free;
  FFill.Free;
  FTimeLineBar.Free;
  FTimeLineBarSections.Free;
  FDefaultSectionFill.Free;
  FTimeLineIndicators.Free;
  inherited;
end;

procedure TTIWSmoothTimeLineAppearance.ObjectChanged(Sender: TObject);
begin
  Changed;
end;

procedure TTIWSmoothTimeLineAppearance.SetDefaultIndicator(
  const Value: TIWAdvSmoothTimeLineBarIndicator);
begin
  if FDefaultIndicator <> value then
  begin
    FDefaultIndicator.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetDefaultSectionFill(
  const Value: TIWGDIPFill);
begin
  if FDefaultSectionFill <> value then
  begin
    FDefaultSectionFill.Assign(value);
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetFill(const Value: TIWGDIPFill);
begin
  if FFill <> value then
  begin
    FFill.Assign(value);
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetHorizontalMargin(
  const Value: integer);
begin
  if FHorizontalMargin <> value then
  begin
    FHorizontalMargin := Value;
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetRange(
  const Value: TIWAdvSmoothTimeLineRange);
begin
  if FRange <> value then
  begin
    FRange.Assign(value);
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetRangeAppearance(
  const Value: TIWAdvSmoothTimeLineRangeAppearance);
begin
  if FRangeAppearance <> value then
  begin
    FRangeAppearance.Assign(value);
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetTimeLineBar(
  const Value: TIWAdvSmoothTimeLineBar);
begin
  if FTimeLineBar <> value then
  begin
    FTimeLineBar.Assign(value);
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetTimeLineBarSections(
  const Value: TIWAdvSmoothTimeLineBarSections);
begin
  if FTimeLineBarSections <> value then
  begin
    FTimeLineBarSections.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetTimeLineIndicators(
  const Value: TIWAdvSmoothTimeLineBarIndicators);
begin
  if FTimeLineIndicators <> value then
  begin
    FTimeLineIndicators.Assign(value);
    Changed;
  end;
end;

procedure TTIWSmoothTimeLineAppearance.SetVerticalMargin(const Value: integer);
begin
  if FVerticalMargin <> Value then
  begin
    FVerticalMargin := Value;
    Changed;
  end;
end;

end.
