{

   This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit UfrmEffect_shadow;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, UfrmEffectBase, StdCtrls, GR32, GR32_Blend, im_Convolution,
  im_Effects, Spin, ExtCtrls, UnViewColorBox;

type
  TfrmEffect_shadow = class(TfrmEffectBase)
    Panel1: TPanel;
    bsSkinButton1: TButton;
    bsSkinButton2: TButton;
    SpinEdit1: TSpinEdit;
    Label7: TLabel;
    bsSkinStdLabel1: TLabel;
    bsSkinStdLabel2: TLabel;
    bsSkinStdLabel3: TLabel;
    SpinEdit2: TSpinEdit;
    ColorBox2: TnViewColorBox;
    ColorBox1: TnViewColorBox;
    Label1: TLabel;
    SpinEdit3: TSpinEdit;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    Label2: TLabel;
    SpinEdit4: TSpinEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure bsSkinButton1Click(Sender: TObject);
    procedure bsSkinButton2Click(Sender: TObject);
  private
    { Private declarations }
    lastaction:integer;
    previewapplyed:boolean;

    procedure ok_select; override;
    procedure raise_effect(bitmap:tbitmap32;rep,lower:integer);
    procedure shadow_effect(bitmap:tbitmap32;
      ShadowOffset:integer;Background,ShadowColor:tcolor);
    procedure imageprocess(var src:tbitmap);
  public
    { Public declarations }
  end;

var
  frmEffect_shadow: TfrmEffect_shadow;

implementation
uses Uconfig, Ufrmmain;

{$R *.dfm}

procedure TfrmEffect_shadow.FormCreate(Sender: TObject);
begin
  inherited;
  PanelPreView.Width:=300;
  PanelPreView.Align:=alLeft;
  Panel1.Align:=alclient;
  lastaction:=0;
  previewapplyed:=false;
end;

procedure TfrmEffect_shadow.FormShow(Sender: TObject);
begin
//  make_thumbimage;
  BitBtn2.SetFocus;
  
  thumb_bitmap32.Assign(org_bitmap32);
  org_bitmap32.SetSize(0,0);
  imagepreview1.Bitmap.Assign(thumb_bitmap32);
  imagepreview1_scale;

  SpinEdit1.Value:=config.getvaluebyinteger('shadow_depth',5);
  SpinEdit4.Value:=config.getvaluebyinteger('shadow_lower',0);
  ColorBox1.Selected:=config.getvaluebyinteger('shadow_backcolor',clWhite);
  ColorBox2.Selected:=config.getvaluebyinteger('shadow_shadowcolor',clgray);
  SpinEdit2.Value:=config.getvaluebyinteger('shadow_shadowdepth',5);
  SpinEdit3.Value:=config.getvaluebyinteger('shadow_blur',6);
  self.CheckBox2.Checked:=boolean(config.getvaluebyinteger('shadow_preview',1));
  lastaction:=config.getvaluebyinteger('shadow_lastaction',1);
  if lastaction=1 then
    self.CheckBox1.Checked:=true
  else
    self.CheckBox3.Checked:=true;

  applyselect.Visible:=true;
end;

procedure TfrmEffect_shadow.ok_select;
begin
  config.setvaluebyinteger('shadow_lastaction',lastaction);
  config.setvaluebyinteger('shadow_depth',SpinEdit1.Value);
  config.setvaluebyinteger('shadow_lower',SpinEdit4.Value);
  config.setvaluebyinteger('shadow_backcolor',ColorBox1.Selected);
  config.setvaluebyinteger('shadow_shadowcolor',ColorBox2.Selected);
  config.setvaluebyinteger('shadow_shadowdepth',SpinEdit2.Value);
  config.setvaluebyinteger('shadow_blur',SpinEdit3.Value);
  config.setvaluebyinteger('shadow_preview',integer(self.CheckBox2.Checked));

  if applyselect.ItemIndex=0 then begin
    if previewapplyed=false then begin
     Screen.Cursor:=crHourglass;
     try
      imagepreview1.Bitmap.Assign(thumb_bitmap32);
      case lastaction of
        1:raise_effect(imagepreview1.Bitmap,round(SpinEdit1.Value),round(SpinEdit4.Value));
        2:shadow_effect(imagepreview1.Bitmap,round(SpinEdit2.Value),
          ColorBox1.Selected,
          ColorBox2.Selected);
      end;
     finally
       screen.Cursor:=crdefault;
     end;
    end;
    exit;
  end;

  frmmain.apply_listimages(applyselect.ItemIndex=1,imageprocess,etshadow,self.Caption);
  self.ModalResult:=mrcancel;
end;

procedure TfrmEffect_shadow.imageprocess(var src:tbitmap);
var
  bitmap:tbitmap32;
begin
  bitmap:=tbitmap32.Create;
  try
    Bitmap.Assign(src);
    case lastaction of
      1:raise_effect(Bitmap,round(SpinEdit1.Value),round(SpinEdit4.Value));
      2:shadow_effect(Bitmap,round(SpinEdit2.Value),
        ColorBox1.Selected,
        ColorBox2.Selected);
    end;
    Bitmap.AssignTo24(src);
  finally
    bitmap.Free;
  end;
end;

procedure TfrmEffect_shadow.bsSkinButton1Click(Sender: TObject);
begin
  screen.Cursor:=crHourglass;
  try
    if self.CheckBox2.Checked then begin
      imagepreview1.Bitmap.Assign(thumb_bitmap32);
      raise_effect(imagepreview1.Bitmap,round(SpinEdit1.Value),round(SpinEdit4.Value));
      previewapplyed:=true;
    end else
      previewapplyed:=false;
    lastaction:=1;
    self.CheckBox1.Checked:=true;
    self.CheckBox3.Checked:=false;
  finally
    screen.Cursor:=crdefault;
  end;
end;

procedure TfrmEffect_shadow.raise_effect(bitmap:tbitmap32;rep,lower:integer);
var
  arect:trect;
  i,j:integer;
begin
  ARect:=rect(0,0,Bitmap.Width,Bitmap.Height);
  j:=(rep*8+3)-(lower*10);
  for I := 0 to rep do begin
    with arect do
       Bitmap.RaiseRectTS(Left, Top, Right, Bottom, j - I * 8);
    InflateRect(arect, -1, -1);
  end;
end;

procedure TfrmEffect_shadow.shadow_effect(bitmap:tbitmap32;
  ShadowOffset:integer;Background,ShadowColor:tcolor);
var
   ShadowBmp: TBitmap32;
   Ray: array [0..24] of Integer;
   I,Z: Integer;
begin
   ShadowBmp := TBitmap32.Create();
   try
      ShadowBmp.SetSize(Bitmap.Width + (2 * ShadowOffset),
           Bitmap.Height + (2 * ShadowOffset));
      ShadowBmp.Clear(Color32(Background));
      ShadowBmp.FillRect(ShadowOffset, ShadowOffset, ShadowOffset +
                          Bitmap.Width, ShadowOffset + Bitmap.Height,
                          Color32(ShadowColor));
{
      // Blur the shadow bitmap
      ray[0]  := 1;  ray[1]  := 1;  ray[2]  := 1;  ray[3]  := 1;  ray[4] := 1;
      ray[5]  := 1;  ray[6]  := 1;  ray[7]  := 1;  ray[8]  := 1;  ray[9] := 1;
      ray[10] := 1;  ray[11] := 1;  ray[12] := 1;  ray[13] := 1;  ray[14] := 1;
      ray[15] := 1;  ray[16] := 1;  ray[17] := 1;  ray[18] := 1;  ray[19] := 1;
      ray[20] := 1;  ray[21] := 1;  ray[22] := 1;  ray[23] := 1;  ray[24] := 1;
      z := 25;
      ApplyConvolution5x5(ShadowBmp,ray,z); // 5x5 convolve
      }

      Effect_GaussianBlur(ShadowBmp,SpinEdit3.Value);

      ShadowBmp.Draw(0, 0, Bitmap);
      Bitmap.Assign(ShadowBmp);
   finally
      ShadowBmp.Free;
   end;
end;

procedure TfrmEffect_shadow.bsSkinButton2Click(Sender: TObject);
begin
  screen.Cursor:=crHourglass;
  try
    if self.CheckBox2.Checked then begin
      imagepreview1.Bitmap.Assign(thumb_bitmap32);
      shadow_effect(imagepreview1.Bitmap,round(SpinEdit2.Value),
        ColorBox1.Selected,
        ColorBox2.Selected);
      previewapplyed:=true;
    end else
      previewapplyed:=false;
    lastaction:=2;
    self.CheckBox1.Checked:=false;
    self.CheckBox3.Checked:=true;
  finally
    screen.Cursor:=crdefault;
  end;
end;

end.
