{***************************************************************************}
{ TMS Smooth Gauge for IntraWeb                                             }
{ for Delphi & C++Builder                                                   }
{                                                                           }
{ written by TMS Software                                                   }
{            copyright © 2012 - 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 iwgauge;

{$I TMSDEFS.INC}

interface

uses
  IWAdvSmoothGauge, 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 = 0; // Minor version nr.
  REL_VER = 0; // Release nr.
  BLD_VER = 2; // 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 async events

type

  TTIWSmoothGauge = class;

  TTIWSmoothGaugeAppearance = class(TPersistent)
  private
    FIWOwner: TTIWSmoothGauge;
    FOuterCircle: TIWAdvSmoothGaugeOuterCircle;
    FOuterRim: TIWAdvSmoothGaugeOuterRim;
    fmaxvalue: integer;
    FValueFont: TFont;
    FValueFormat: string;
    FArc: TIWAdvSmoothGaugeArc;
    FInnerCircle: TIWAdvSmoothGaugeInnerCircle;
    FSections: TIWAdvSmoothGaugeSections;
    fminvalue: integer;
    fFont: TFont;
    FSubDivWidth: integer;
    fnoOfSubDivisions: Integer;
    FNeedleType: TIWAdvSmoothGaugeNeedleType;
    FDivWidth: integer;
    fSubDivColor: TColor;
    FCurrentValue: Double;
    fdialText: string;
    fnoOfDivisions: Integer;
    fDivColor: TColor;
    FDigit: TIWAdvSmoothGaugeDigit;
    FNeedle: TIWAdvSmoothGaugeNeedle;
    procedure SetArc(const Value: TIWAdvSmoothGaugeArc);
    procedure SetDialText(const Value: string);
    procedure SetDigit(const Value: TIWAdvSmoothGaugeDigit);
    procedure SetDivColor(const Value: TColor);
    procedure SetDivWidth(const Value: integer);
    procedure SetFont(const Value: TFont);
    procedure SetInnerCircle(const Value: TIWAdvSmoothGaugeInnerCircle);
    procedure SetMaxValue(const Value: integer);
    procedure SetMinValue(const Value: integer);
    procedure SetNeedle(const Value: TIWAdvSmoothGaugeNeedle);
    procedure SetNeedleType(const Value: TIWAdvSmoothGaugeNeedleType);
    procedure SetNoOfDivisions(const Value: Integer);
    procedure SetNoOfSubDivisions(const Value: Integer);
    procedure SetOuterCircle(const Value: TIWAdvSmoothGaugeOuterCircle);
    procedure SetOuterRim(const Value: TIWAdvSmoothGaugeOuterRim);
    procedure SetSections(const Value: TIWAdvSmoothGaugeSections);
    procedure SetSubDivColor(const Value: TColor);
    procedure SetSubDivWidth(const Value: integer);
    procedure SetValue(const Value: Double);
    procedure SetValueFont(const Value: TFont);
    procedure SetValueFormat(const Value: string);
  protected
    procedure Changed;
    procedure DigitChanged(Sender: TObject);
    procedure OuterCircleChanged(Sender: TObject);
    procedure InnerCircleChanged(Sender: TObject);
    procedure OuterRimChanged(Sender: TObject);
    procedure NeedleChanged(Sender: TObject);
    procedure ArcChanged(Sender: TObject);
    procedure SectionsChanged(Sender: TObject);
  public
    constructor Create(IWOwner: TTIWSmoothGauge; AOwner: TIWAdvSmoothGauge);
    destructor Destroy; override;
    property Sections: TIWAdvSmoothGaugeSections read FSections write SetSections;
  published
    property MinimumValue: integer read fminvalue write SetMinValue default 0;
    property MaximumValue: integer read fmaxvalue write SetMaxValue default 100;
    property Value: Double read FCurrentValue write SetValue;
    property Digit: TIWAdvSmoothGaugeDigit read FDigit write SetDigit;
    property OuterCircle: TIWAdvSmoothGaugeOuterCircle read FOuterCircle write SetOuterCircle;
    property InnerCircle: TIWAdvSmoothGaugeInnerCircle read FInnerCircle write SetInnerCircle;
    property OuterRim: TIWAdvSmoothGaugeOuterRim read FOuterRim write SetOuterRim;
    property Needle: TIWAdvSmoothGaugeNeedle read FNeedle write SetNeedle;
    property Arc: TIWAdvSmoothGaugeArc read FArc write SetArc;
    property DivisionCount: Integer read fnoOfDivisions write SetNoOfDivisions default 10;
    property SubDivisionCount: Integer read fnoOfSubDivisions write SetNoOfSubDivisions default 3;
    property DivisionColor: TColor read fDivColor write SetDivColor default $00FC7C;
    property SubDivisionColor: TColor read fSubDivColor write SetSubDivColor default $00FC7C;
    property DivisionWidth: integer read FDivWidth write SetDivWidth default 5;
    property SubDivisionWidth: integer read FSubDivWidth write SetSubDivWidth default 2;
    property DialText: string read fdialText write SetDialText;
    property Font: TFont read fFont write SetFont;
    property ValueFont: TFont read FValueFont write SetValueFont;
    property ValueFormat: string read FValueFormat write SetValueFormat;
    property NeedleType: TIWAdvSmoothGaugeNeedleType read FNeedleType write SetNeedleType default ntPointer;
  end;

  TTIWSmoothGauge = class(TIWControl, ITMSStyle)
  private
    FInternal: Boolean;
    FNoResize: Boolean;
    FVersion: string;
    FChanged: boolean;
    FUpdateCount: integer;
    FGauge: TIWAdvSmoothGauge;
    FImageType: TImageType;
    FImageQuality: Integer;
    FAppearance: TTIWSmoothGaugeAppearance;
    FOnAsyncValueChanged: TIWAdvSmoothGaugeValueChanged;
    FOnValueChanged: TIWAdvSmoothGaugeValueChanged;
    function GetVersion: string;
    function OutputImage: string;
    procedure SetImageType(const Value: TImageType);
    procedure SetImageQuality(const Value: Integer);
    procedure SetAppearance(const Value: TTIWSmoothGaugeAppearance);
  protected
    procedure DoAsyncValueChanged(AParams: TStringList);
    procedure DoValueChanged(Sender: TObject; value: Double);
    function ImageHTML(const ASrc,BSrc: string; AContext: TIWBaseComponentContext): TIWHTMLTag;
    procedure SetValue(const value:string); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Resize; override;
    procedure ApplyAppearance;
    procedure GaugeChanged(Sender: TObject);
    procedure IWPaint; override;
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
    function RenderAsync(AContext: TIWBaseHTMLComponentContext): TIWXMLTag; override;
    function GetVersionNr: Integer; virtual;
    function GetVersionString: string; virtual;
    procedure SetComponentStyle(AStyle: TTMSStyle);
  published
    property Appearance: TTIWSmoothGaugeAppearance 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 OnAsyncValueChanged: TIWAdvSmoothGaugeValueChanged read FOnAsyncValueChanged write FOnAsyncValueChanged;
    property OnValueChanged: TIWAdvSmoothGaugeValueChanged read FOnValueChanged write FOnValueChanged;
  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;


{ TTIWSmoothGauge }

function TTIWSmoothGauge.RenderAsync(
  AContext: TIWBaseHTMLComponentContext): TIWXMLTag;
var
  js: string;
  ImgName: string;
begin
  ImgName := '';

  Result := TIWXMLTag.CreateTag('control');
  try
    Result.AddStringParam('id', HTMLName);
    Result.AddStringParam('type', 'TTIWSmoothGauge');
    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 TTIWSmoothGauge.GetVersion: string;
begin
  Result := FVersion;
end;

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

function TTIWSmoothGauge.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 TTIWSmoothGauge.ApplyAppearance;
begin
  FGauge.Width := Width;
  FGauge.Height := Height;
  FGauge.MinimumValue := Appearance.MinimumValue;
  FGauge.MaximumValue := Appearance.MaximumValue;
  FGauge.value := Appearance.Value;
  FGauge.Digit.Assign(Appearance.Digit);
  FGauge.OuterCircle.Assign(Appearance.outercircle);
  FGauge.InnerCircle.Assign(Appearance.InnerCircle);
  FGauge.OuterRim.assign(Appearance.outerrim);
  Fgauge.needle.assign(Appearance.needle);
  FGauge.Arc.assign(Appearance.Arc);
  FGauge.divisionCount := Appearance.DivisionCount;
  FGauge.SubDivisionCount := Appearance.SubDivisionCount;
  FGauge.DivisionColor := Appearance.DivisionColor;
  FGauge.SubDivisionColor := Appearance.SubDivisionColor;
  FGauge.DivisionWidth := Appearance.DivisionWidth;
  FGauge.SubDivisionWidth := Appearance.SubDivisionWidth;
  FGauge.DialText := Appearance.DialText;
  FGauge.font.Assign(Appearance.Font);
  FGauge.ValueFont.Assign(Appearance.ValueFont);
  FGauge.ValueFormat := Appearance.ValueFormat;
  FGauge.needleType := Appearance.needletype;
  FGauge.sections.Assign(Appearance.Sections);
end;

constructor TTIWSmoothGauge.Create(AOwner: TComponent);
begin
  inherited;
  FGauge := TIWAdvSmoothGauge.Create(Self);
  FGauge.OnChange := GaugeChanged;
  FGauge.OnValueChanged := DoValueChanged;
  Fgauge.Animation := false;
  FAppearance := TTIWSmoothGaugeAppearance.Create(Self, FGauge);
  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 := FGauge.Width;
  Height := FGauge.Height;
  FNoResize := false;
  FUpdateCount := 0;
  FVersion := GetVersionString;  
end;

destructor TTIWSmoothGauge.Destroy;
begin
  FAppearance.free;
  FGauge.Free;
  inherited;
end;

procedure TTIWSmoothGauge.DoAsyncValueChanged(AParams: TStringList);
begin
  if FInternal then
    Appearance.Value := FGauge.Value;
  if Assigned(OnAsyncValueChanged) then
    OnAsyncValueChanged(Self, Appearance.Value);
end;

procedure TTIWSmoothGauge.DoValueChanged(Sender: TObject; value: Double);
begin
  if FInternal then
    Appearance.Value := FGauge.Value;
  if Assigned(OnValueChanged) then
    OnValueChanged(Sender, Value);
end;

procedure TTIWSmoothGauge.IWPaint;
begin
  if not (Assigned(FGauge)) then
  begin
    inherited;
    Exit;
  end;

  inc(FUpdateCount);

  if FChanged then
  begin
    ApplyAppearance;
  end;

  FChanged := false;

  // design time painting
  FGauge.DrawGauge(Canvas);
  
  dec(FUpdateCount);
end;

function TTIWSmoothGauge.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+'DoMouseUp(e, el)');
    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 = ""+x+";"+y');

    if Assigned(OnValueChanged) then
      Add('return SubmitClick('#39+HTMLName+#39', 0, '#39'false'#39');'#13)
    else
      Add('processAjaxEvent(''onValueChanged'', '
        + HTMLControlImplementation.IWCLName
        + ',''' + HTMLName + '.' + 'DoAsyncValueChanged' + ''','
        + 'true' + ', null, '
        + 'true' + ');');

    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+'DoMouseUp(event, this)');
  end;
  with Result.Contents.AddTag('INPUT') do
  begin
    AddStringParam('TYPE','hidden');
    AddStringParam('NAME',HTMLName+'');
    AddStringParam('ID',HTMLName+'_INPUT');
  end;
end;


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

  if Assigned(FGauge) 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}
    FGauge.SaveToImage(ImgName, Width, Height, ImageType, ImageQuality);
    {$ENDIF}

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

    try
      FGauge.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 TTIWSmoothGauge.GaugeChanged(Sender: TObject);
begin
  if FUpdateCount = 0 then
  begin
    FChanged := true;
    Invalidate;
  end;
end;

function TTIWSmoothGauge.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
var
  ImgName, ImgHot: string;
begin
  ImgName := '';
  ImgHot := '';
  
  //Register async refresh
  AContext.WebApplication.RegisterCallBack(HTMLName + '.DoAsyncValueChanged', DoAsyncValueChanged);

  ImgName := OutputImage;

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

procedure TTIWSmoothGauge.Resize;
begin
  inherited;
  if not FNoResize and Assigned(FGauge) then
  begin
    FGauge.Width := Width;
    FGauge.Height := Height;
  end;
end;

procedure TTIWSmoothGauge.SetAppearance(const Value: TTIWSmoothGaugeAppearance);
begin
  if FAppearance <> value then
  begin
    FAppearance.Assign(Value);
    GaugeChanged(Self);
  end;
end;

procedure TTIWSmoothGauge.SetComponentStyle(AStyle: TTMSStyle);
begin
  with Appearance do
  begin
    // TODO : do color settings here
    case AStyle of
      tsOffice2003Blue:
        begin
          Arc.Color := $D68759;
          InnerCircle.Color := $D68759;
          OuterCircle.Color := $00FFD2AF;
          Arc.Threshold.Color := $00FFD2AF;
          Digit.BackGroundColor := $D68759;
          Digit.Color := $962D00;
          DivisionColor := $962D00;
          SubDivisionColor := $962D00;
          Needle.Color := $962D00;
          Needle.InnerCenterColor := $00FFD2AF;
          Needle.OuterCenterColor := $933803;
          Needle.ShineColor := $D68759;
          ValueFont.Color := $962D00;
        end;
      tsOffice2003Silver:
      begin
          Arc.Color := $BDA4A5;
          InnerCircle.Color := $BDA4A5;
          OuterCircle.Color := $00E6D8D8;
          Arc.Threshold.Color := $00E6D8D8;
          Digit.BackGroundColor := $BDA4A5;
          Digit.Color := $947C7C;
          DivisionColor := $947C7C;
          SubDivisionColor := $947C7C;
          Needle.Color := $947C7C;
          Needle.InnerCenterColor := $00E6D8D8;
          Needle.InnerCenterColorTo := $00E6D8D8;
          Needle.OuterCenterColor := $957475;
          Needle.ShineColor := $BDA4A5;
          ValueFont.Color := $947C7C;
      end;
      tsOffice2003Olive:
      begin
          Arc.Color := $82C0AF;
          InnerCircle.Color := $82C0AF;
          OuterCircle.Color := $CFF0EA;
          Arc.Threshold.Color := $CFF0EA;
          Digit.BackGroundColor := $82C0AF;
          Digit.Color := $447A63;
          DivisionColor := $447A63;
          SubDivisionColor := $447A63;
          Needle.Color := $447A63;
          Needle.InnerCenterColor := $447A63;
          Needle.InnerCenterColorTo := $447A63;
          Needle.OuterCenterColor := $447A63;
          Needle.ShineColor := $447A63;
          ValueFont.Color := $447A63;
      end;
      tsOffice2003Classic:
      begin
          Arc.Color := $808080;
          InnerCircle.Color := $808080;
          OuterCircle.Color := $00F2F2F2;
          Arc.Threshold.Color := $00F2F2F2;
          Digit.BackGroundColor := $808080;
          Digit.Color := $808080;
          DivisionColor := $808080;
          SubDivisionColor := $808080;
          Needle.Color := $808080;
          Needle.InnerCenterColor := $00F2F2F2;
          Needle.InnerCenterColorTo := $00F2F2F2;
          Needle.OuterCenterColor := $808080;
          Needle.ShineColor := $808080;
          ValueFont.Color := $808080;
      end;
      tsOffice2007Luna:
      begin
          Arc.Color := $FFEFE3;
          InnerCircle.Color := $00FFD2AF;
          OuterCircle.Color := $00FFD2AF;
          Arc.Threshold.Color := $00FFD2AF;
          Digit.BackGroundColor := $FFEFE3;
          Digit.Color := $962D00;
          DivisionColor := $962D00;
          SubDivisionColor := $962D00;
          Needle.Color := $FFD2AF;
          Needle.InnerCenterColor := $00FFD2AF;
          Needle.InnerCenterColorTo := $00FFD2AF;
          Needle.OuterCenterColor := $FFD1AD;
          Needle.ShineColor := $FFEFE3;
          ValueFont.Color := $962D00;
      end;
      tsOffice2007Obsidian:
      begin
          Arc.Color := $F2F1F0;
          InnerCircle.Color := $5C534C;
          OuterCircle.Color := $5C534C;
          Arc.Threshold.Color := $5C534C;
          Digit.BackGroundColor := $F2F1F0;
          Digit.Color := $F2F1F0;
          DivisionColor := $F2F1F0;
          SubDivisionColor := $F2F1F0;
          Needle.Color := $F2F1F0;
          Needle.InnerCenterColor := $F2F1F0;
          Needle.InnerCenterColorTo := $F2F1F0;
          Needle.OuterCenterColor := $FFD1AD;
          Needle.ShineColor := $F2F1F0;
          ValueFont.Color := $F2F1F0;
      end;
      tsWindowsXP:
      begin
          Arc.Color := $5C534C;
          InnerCircle.Color := clBtnFace;
          OuterCircle.Color := clBtnFace;
          Arc.Threshold.Color := clBtnFace;
          Digit.BackGroundColor := $5C534C;
          Digit.Color := $5C534C;
          DivisionColor := $5C534C;
          SubDivisionColor := $5C534C;
          Needle.Color := $5C534C;
          Needle.InnerCenterColor := $5C534C;
          Needle.InnerCenterColorTo := $5C534C;
          Needle.OuterCenterColor := $FFD1AD;
          Needle.ShineColor := $5C534C;
          ValueFont.Color := $5C534C;
      end;
      tsWhidbey:
      begin
          Arc.Color := $F5F9FA;
          InnerCircle.Color := $EBEEEF;
          OuterCircle.Color := $EBEEEF;
          Arc.Threshold.Color := $5C534C;
          Digit.BackGroundColor := $F5F9FA;
          Digit.Color := $5C534C;
          DivisionColor := $5C534C;
          SubDivisionColor := $5C534C;
          Needle.Color := $5C534C;
          Needle.InnerCenterColor := $F5F9FA;
          Needle.InnerCenterColorTo := $F5F9FA;
          Needle.OuterCenterColor := $FFD1AD;
          Needle.ShineColor := $F5F9FA;
          ValueFont.Color := $5C534C;
      end;
      tsCustom: ;
      tsOffice2007Silver:
      begin
          Arc.Color := $00CAC1BA;
          InnerCircle.Color := $00CAC1BA;
          OuterCircle.Color := $00CAC1BA;
          Arc.Threshold.Color := $F8F7F6;
          Digit.BackGroundColor := $00CAC1BA;
          Digit.Color := $5C534C;
          DivisionColor := $5C534C;
          SubDivisionColor := $5C534C;
          Needle.Color := $5C534C;
          Needle.InnerCenterColor := $F5F9FA;
          Needle.InnerCenterColorTo := $F5F9FA;
          Needle.OuterCenterColor := $FFD1AD;
          Needle.ShineColor := $F8F7F6;
          ValueFont.Color := $5C534C;
      end;
    tsWindowsvista:
      begin
          Arc.Color := $E0DAD1;
          InnerCircle.Color := $F3F1EA;
          OuterCircle.Color := $ADA9A5;
          Arc.Threshold.Color := $D8CEC2;
          Digit.BackGroundColor := $FFFFFF;
          Digit.Color := clBlack;
          DivisionColor := $B3ADA2;
          SubDivisionColor := $D2D9DE;
          Needle.Color := $989684;
          Needle.InnerCenterColor := $FDF8F1;
          Needle.InnerCenterColorTo := clBlack;
          Needle.OuterCenterColor := $FCEFD5;
          Needle.ShineColor := $D1d1d1;
          ValueFont.Color := clBlack;
      end;
    tsWindows7:
      begin
          Arc.Color := $E0DAD1;
          InnerCircle.Color := $F3F1EA;
          OuterCircle.Color := $ADA9A5;
          Arc.Threshold.Color := $D8CEC2;
          Digit.BackGroundColor := $FFFFFF;
          Digit.Color := clBlack;
          DivisionColor := $B3ADA2;
          SubDivisionColor := $D2D9DE;
          Needle.Color := $989684;
          Needle.InnerCenterColor := $FDF8F1;
          Needle.InnerCenterColorTo := clBlack;
          Needle.OuterCenterColor := $FCEFD5;
          Needle.ShineColor := $D1d1d1;
          ValueFont.Color := clBlack;
      end;
    tsTerminal:
      begin
          Arc.Color := clBtnFace;
          InnerCircle.Color := clBtnFace;
          OuterCircle.Color := clBtnFace;
          Arc.Threshold.Color := clGray;
          Digit.BackGroundColor := clBtnFace;
          Digit.Color := clBlack;
          DivisionColor := clGray;
          SubDivisionColor := clGray;
          Needle.Color := clGray;
          Needle.InnerCenterColor := clGray;
          Needle.InnerCenterColorTo := clGray;
          Needle.OuterCenterColor := clHighLight;
          Needle.ShineColor := clNone;
          ValueFont.Color := clBlack;
      end;
    end;

    Font.Color := ValueFont.Color;
  end;
end;

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

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

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

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

    if vp > 0 then
    begin
      x := strtoint(Copy(varvalue, 0, Pos(';', varvalue) - 1));
      y := strtoint(Copy(varvalue, Pos(';', varvalue) + 1 , Length(varvalue) - Pos(';', varvalue)));
      FInternal := true;
      if Assigned(Fgauge) then
        FGauge.XYToScale(X, Y);
      FInternal := false;
      inherited SetValue(varvalue);
    end;
  end
end;

{ TTIWSmoothGaugeAppearance }

procedure TTIWSmoothGaugeAppearance.ArcChanged(Sender: TObject);
begin
  Changed;
end;

procedure TTIWSmoothGaugeAppearance.Changed;
begin
  FIWOwner.GaugeChanged(Self);
end;

constructor TTIWSmoothGaugeAppearance.Create(IWOwner: TTIWSmoothGauge; AOwner: TIWAdvSmoothGauge);
begin
  FIWOwner := IWOwner;
  FFont := TFont.Create;
  FFont.Color := $00FC7C;
  FValueFont := TFont.Create;
  FValueFont.Color := $00FC7C;
  FValueFont.Size := 11;
  FFont.Color := $00FC7C;
  FFont.Size := 14;

  {$IFNDEF DELPHI9_LVL}
  FFont.Name := 'Tahoma';
  FValueFont.Name := 'Tahoma';
  {$ENDIF}

  FDivWidth := 5;
  FSubDivWidth := 2;
  FDivColor := $00FC7C;
  FSubDivColor := $00FC7C;

  FValueFormat := '000.00';

  fnoOfDivisions := 10;
  fnoOfSubDivisions := 3;
  fminValue := 0;
  fmaxValue := 100;
  fcurrentValue := 0;

  FDigit := TIWAdvSmoothGaugeDigit.Create(AOwner);
  FDigit.OnChange := DigitChanged;

  FOuterCircle := TIWAdvSmoothGaugeOuterCircle.Create(AOwner);
  FOuterCircle.OnChange := OuterCircleChanged;

  FInnerCircle := TIWAdvSmoothGaugeInnerCircle.Create(AOwner);
  FInnerCircle.OnChange := InnerCircleChanged;

  FOuterRim := TIWAdvSmoothGaugeOuterRim.Create(AOwner);
  FOuterRim.OnChange := OuterRimChanged;

  FNeedle := TIWAdvSmoothGaugeNeedle.Create(AOwner);
  FNeedle.OnChange := NeedleChanged;

  FArc := TIWAdvSmoothGaugeArc.Create(AOwner);
  FArc.OnChange := ArcChanged;

  FSections := TIWAdvSmoothGaugeSections.Create(AOwner);
  FSections.OnChange := SectionsChanged;

  FNeedleType := ntPointer;
end;

destructor TTIWSmoothGaugeAppearance.Destroy;
begin
  FArc.Free;
  FDigit.Free;
  FOuterCircle.Free;
  FInnerCircle.Free;
  FFont.Free;
  FValueFont.Free;
  FNeedle.Free;
  FOuterRim.Free;
  FSections.Free;
  inherited;
end;

procedure TTIWSmoothGaugeAppearance.DigitChanged(Sender: TObject);
begin
  Changed;
end;

procedure TTIWSmoothGaugeAppearance.InnerCircleChanged(Sender: TObject);
begin
  Changed;
end;

procedure TTIWSmoothGaugeAppearance.NeedleChanged(Sender: TObject);
begin
  Changed;
end;

procedure TTIWSmoothGaugeAppearance.OuterCircleChanged(Sender: TObject);
begin
  Changed;
end;

procedure TTIWSmoothGaugeAppearance.OuterRimChanged(Sender: TObject);
begin
  Changed;
end;

procedure TTIWSmoothGaugeAppearance.SectionsChanged(Sender: TObject);
begin
  Changed;
end;

procedure TTIWSmoothGaugeAppearance.SetArc(const Value: TIWAdvSmoothGaugeArc);
begin
  if FArc <> Value then
  begin
    FArc.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetDialText(const Value: string);
begin
  if FDialText <> Value then
  begin
    fdialText := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetDigit(const Value: TIWAdvSmoothGaugeDigit);
begin
  if FDigit <> Value then
  begin
    FDigit := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetDivColor(const Value: TColor);
begin
  if FDivColor <> value then
  begin
    fDivColor := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetDivWidth(const Value: integer);
begin
  if FDivWidth <> value then
  begin
    FDivWidth := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetFont(const Value: TFont);
begin
  if FFont <> Value then
  begin
    fFont.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetInnerCircle(
  const Value: TIWAdvSmoothGaugeInnerCircle);
begin
  if FInnerCircle <> value then
  begin
    FInnerCircle.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetMaxValue(const Value: integer);
begin
  if FMaxValue <> value then
  begin
    fmaxvalue := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetMinValue(const Value: integer);
begin
  if FMinValue <> value then
  begin
    fminvalue := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetNeedle(
  const Value: TIWAdvSmoothGaugeNeedle);
begin
  if FNeedle <> value then
  begin
    FNeedle.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetNeedleType(
  const Value: TIWAdvSmoothGaugeNeedleType);
begin
  if FNeedleType <> value then
  begin
    FNeedleType := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetNoOfDivisions(const Value: Integer);
begin
  if FNoOfDivisions <> value then
  begin
    fnoOfDivisions := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetNoOfSubDivisions(const Value: Integer);
begin
  if FNoOfSubDivisions <> value then
  begin
    fnoOfSubDivisions := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetOuterCircle(
  const Value: TIWAdvSmoothGaugeOuterCircle);
begin
  if Foutercircle <> value then
  begin
    FOuterCircle.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetOuterRim(
  const Value: TIWAdvSmoothGaugeOuterRim);
begin
  if FOuterRim <> value then
  begin
    FOuterRim.Assign(value);
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetSections(
  const Value: TIWAdvSmoothGaugeSections);
begin
  if FSections <> value then
  begin
    FSections.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetSubDivColor(const Value: TColor);
begin
  if FSubDivColor <> value then
  begin
    fSubDivColor := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetSubDivWidth(const Value: integer);
begin
  if FSubDivWidth <> value then
  begin
    FSubDivWidth := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetValue(const Value: Double);
begin
  if FcurrentValue <> value then
  begin
    FCurrentValue := Value;
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetValueFont(const Value: TFont);
begin
  if FValueFont <> value then
  begin
    FValueFont.Assign(Value);
    Changed;
  end;
end;

procedure TTIWSmoothGaugeAppearance.SetValueFormat(const Value: string);
begin
  if FvalueFormat <> value then
  begin
    FValueFormat := Value;
    Changed;
  end;
end;

end.
