unit WavesOutWin;

{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, Messages, SysUtils, Forms, Classes, Dialogs, Controls, StdCtrls, Buttons, ComCtrls,
  Menus, ExtCtrls, Grids, Graphics, INIFiles,ShellAPI,
  _waveenc, _mp3enc, _oggenc, _wavesout_const, _MDXWin_const, _ID3_const;

type
  TWavesOut = class(TForm)
    encPanel: TPanel;
    encGrid: TStringGrid;
    SizeChangeTimer: TTimer;
    PrgBar: TProgressBar;
    InfoLbl: TStaticText;
    SystemBtnPanel: TPanel;
    NewShape: TShape;
    CloseShape: TShape;
    SaveShape: TShape;
    LoadShape: TShape;
    CloseLbl: TLabel;
    SaveLbl: TLabel;
    LoadLbl: TLabel;
    NewLbl: TLabel;
    GripImg: TImage;
    CreateShape: TShape;
    SetupShape: TShape;
    SetupLbl: TLabel;
    CreateLbl: TLabel;
    encGridPopupMenu: TPopupMenu;
    Menu_ID3: TMenuItem;
    Menu_SaveAs: TMenuItem;
    Menu_TestPlay: TMenuItem;
    Menu_OneDecode: TMenuItem;
    Menu_Delete: TMenuItem;
    SaveWaveDlg: TSaveDialog;
    LoadMPPDlg: TOpenDialog;
    SaveMPPDlg: TSaveDialog;
    StartupTimer: TTimer;
    SectionLst: TListBox;
    SortPopupMenu: TPopupMenu;
    Menu_SortFullPathUp: TMenuItem;
    Menu_SortFilenameUp: TMenuItem;
    Menu_SortTitleUp: TMenuItem;
    Menu_SortWaveFilenameUp: TMenuItem;
    Menu_SortFullPathDown: TMenuItem;
    Menu_SortFilenameDown: TMenuItem;
    Menu_SortTitleDown: TMenuItem;
    Menu_SortWaveFilenameDown: TMenuItem;
    SortShape: TShape;
    SortLbl: TLabel;
    encGridImg: TImage;
    procedure WMDROPFILES(var msg:TWMDROPFILES);message WM_DROPFILES;
    procedure encGridDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure encGridDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure encGridDblClick(Sender: TObject);
    procedure encGridDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure FormResize(Sender: TObject);
    procedure SizeChangeTimerTimer(Sender: TObject);
    procedure GripImgMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure GripImgMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure GripImgMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure encPanelMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure encPanelMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure encPanelMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure NewLblClick(Sender: TObject);
    procedure encGridMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Menu_ID3Click(Sender: TObject);
    procedure Menu_SaveAsClick(Sender: TObject);
    procedure Menu_DeleteClick(Sender: TObject);
    procedure Menu_TestPlayClick(Sender: TObject);
    procedure Menu_OneDecodeClick(Sender: TObject);
    procedure SetupLblClick(Sender: TObject);
    procedure CloseLblClick(Sender: TObject);
    procedure CreateLblClick(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SaveLblClick(Sender: TObject);
    procedure LoadLblClick(Sender: TObject);
    procedure StartupTimerTimer(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure encGridMouseWheelDown(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure encGridMouseWheelUp(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure Menu_SortFullPathUpClick(Sender: TObject);
    procedure Menu_SortFilenameUpClick(Sender: TObject);
    procedure Menu_SortTitleUpClick(Sender: TObject);
    procedure Menu_SortWaveFilenameUpClick(Sender: TObject);
    procedure Menu_SortFullPathDownClick(Sender: TObject);
    procedure Menu_SortFilenameDownClick(Sender: TObject);
    procedure Menu_SortTitleDownClick(Sender: TObject);
    procedure Menu_SortWaveFilenameDownClick(Sender: TObject);
    procedure SortLblMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private 宣言 }
    waveenc:Twaveenc;
    mp3enc:Tmp3enc;
    oggenc:Toggenc;
    isEncoding:boolean;
    encFiles:TencFiles;
    MBarFlag:boolean;
    MBarX,MBarY:integer;
    DlgDrag:boolean;
    Dlgmx:integer;
    Dlgmy:integer;
    MPPSetting:TMPPSetting;
    procedure EncodeStart;
    function  EncodeProcess(idx:integer):boolean;
    procedure EncodeEnd;
    procedure LoadMPP(MPPFilename:string);
    procedure LoadMPP01(MPPFilename:string);
    procedure LoadMPP02(MPPFilename:string);
    procedure SaveMPP(var encFiles:TencFiles;MPPFilename:string);
    function CheckEncorder:boolean;
    procedure SetGridRowCount(cnt:integer);
  public
    { Public 宣言 }
    procedure LoadSkin;
    procedure AddDragFiles(DragFiles:TDragFiles);
    procedure NewFileList;
    procedure AddFileList(const _FullPath,_Title,_WaveFilename:string;const _ID3:TID3);
    procedure SortFileList(SortKey:integer;UpDown:boolean);
    procedure SwapFileList(const idx1,idx2:integer);
    procedure DeleteFileList(const idx:integer);
    procedure WaveProgressEvent(TotalClock,MesureClock:integer);
    procedure GogoTeaProgressEvent(Sender:TObject; nowFrames:integer; AllFrames:integer);
  end;

var
  WavesOut: TWavesOut;

implementation

uses MainWin, ID3EditDlg, KDDWin, SetMPPDlg, waveencExistDlg,
     _MDXWinINI,_const,_Vis_const,_m_Tools, _PicTools,_MainFileCtl,
     _GridTool,_filebuf,_gFileInfo,_SndDrv_const,DX3Drap,
     _GridScroll,_GridScroll_Rap,_CSkin,_Vis,_Images;

{$R *.dfm}

procedure SetShapeLblColor(var Lbl:TLabel;var Shape:TShape;const mode:boolean);
begin
  if mode=True then begin
    Lbl.Font.Color:=CSkin.dwEtcBright;
    Shape.Pen.Color:=CSkin.dwEtcBright;
    end else begin
    Lbl.Font.Color:=CSkin.dwEtcMask;
    Shape.Pen.Color:=CSkin.dwEtcMask;
  end;
end;

procedure TWavesOut.LoadSkin;
  procedure SetLabel(var Lb:TStaticText);
  begin
    Lb.Color:=CSkin.dwEtcBG;
    Lb.Font.Color:=CSkin.dwEtcBright;
  end;
begin
  MakeBlankImg(GripImg,pf24bit);
  with GripImg do begin
    Images.DrawSizeGrip(Picture.Bitmap,0,0,CSkin.ColEtcBG,CSkin.ColEtcFrameGrip);
  end;
  GripImg.Refresh;

  encPanel.Color:=CSkin.dwEtcBG;
  SystemBtnPanel.Color:=CSkin.dwEtcBG;

  SetLabel(InfoLbl);
  SetShapeLblColor(NewLbl,NewShape,True);
  SetShapeLblColor(LoadLbl,LoadShape,True);
  SetShapeLblColor(SaveLbl,SaveShape,True);
  SetShapeLblColor(CloseLbl,CloseShape,True);
  SetShapeLblColor(CreateLbl,CreateShape,True);
  SetShapeLblColor(SetupLbl,SetupShape,True);
  SetShapeLblColor(SortLbl,SortShape,True);

  with encGrid do begin
    FixedColor:=CSkin.dwEtcGridFixedBG;
    Color:=CSkin.dwEtcGridBG;
    Font.Color:=CSkin.dwEtcGridText;
  end;
  encGrid.Refresh;
end;

procedure TWavesOut.WMDROPFILES(var msg:TWMDROPFILES);
var
  Drop:hdrop;
  index:longint;
  Filename:string;
  filebuf:array[0..1024] of char;
  cnt:integer;
  idxcnt:integer;
  errmsg:string;
  nofile:boolean;
  isfolder:boolean;
  isnetwork:boolean;
  isnotsupport:boolean;
  procedure RegFile(Filename:string);
  var
    gfi:TgFileInfo;
  begin
    gfi:=TgFileInfo.Create;
    gfi.SetFileInfo(Filename,False);
    if gfi.GetDriverMode=DriverModeUnknown then begin
      isnotsupport:=True;
      end else begin
      with Main.DragFiles do begin
        Enabled:=True;
        Count:=0;
        SetLength(DragFile,Count+1);
        with DragFile[Count] do begin
          FullPath:=Filename;
          gfi.LoadTitleFromFile;
          Title:=gfi.GetCompactTitle;
          ClearID3(ID3);
        end;
        inc(Count);
      end;
      if Main.DragFiles.Enabled=True then begin
        WavesOut.encGridDragDrop(nil,nil,0,0);
        Main.DragFiles.Enabled:=False;
      end;
    end;
    gfi.Free;
  end;
begin
  Filename:=StringOfChar(' ',1024);
  Drop:=msg.Drop;
  index:=DragQueryFile(Drop,$FFFFFFFF,nil,0);
  if index=0 then begin
    DragFinish(Drop);
    exit;
  end;

  nofile:=False;
  isfolder:=False;
  isnetwork:=False;
  isnotsupport:=False;

  for idxcnt:=0 to index-1 do begin
    DragQueryFile(Drop,idxcnt,filebuf,1024);
    Filename:='';
    cnt:=0;
    while ((filebuf[cnt]<>char($00)) and (cnt<1024)) do begin
      Filename:=Filename+filebuf[cnt];
      inc(cnt);
    end;
    if DirectoryExists(Filename)=True then begin
      Filename:='';
      isfolder:=True;
      end else begin
      if FileExists(Filename)=False then begin
        Filename:='';
        nofile:=True;
      end;
    end;
    if Filename<>'' then begin
      if copy(Filename,1,2)='\\' then begin
        isnetwork:=True;
        end else begin
        RegFile(Filename);
      end;
    end;
  end;
  DragFinish(Drop);

  errmsg:='';
  if nofile=True then errmsg:=errmsg+'ファイルが見つかりませんでした。'+CRLF;
  if isfolder=True then errmsg:=errmsg+'フォルダ内一括登録は未対応です。'+CRLF;
  if isnetwork=True then errmsg:=errmsg+'ネットワーク経由でのドラッグアンドドロップはサポートされていません。'+CRLF+'ネットワークドライブを割り当て場合は使用可能です。'+CRLF;
  if isnotsupport=True then errmsg:=errmsg+'対応していないファイル形式です。'+CRLF;

  if errmsg<>'' then begin
    ShowMessage('以下のエラーが検出されました。'+CRLF+CRLF+errmsg);
  end;
end;

procedure TWavesOut.FormCreate(Sender: TObject);
begin
  waveenc:=Twaveenc.Create;
  waveenc.Init;
  mp3enc:=Tmp3enc.Create;
  mp3enc.Init;
  oggenc:=Toggenc.Create;
  oggenc.Init;

  DragAcceptFiles(WavesOut.Handle,True);

  encFiles.Count:=0;
  isEncoding:=False;

  AdjustWindowSize(Screen.Width,Screen.Height,MainINI.WavesPos);
  with MainINI.WavesPos do begin
    WavesOut.Left:=Left;
    WavesOut.Top:=Top;
    WavesOut.Width:=Width;
    WavesOut.Height:=Height;
  end;

  GS_WavesOut:=TGridScroll.Create;
  GS_WavesOut.LinkComponent(encGrid,encGridImg);

  with encGrid do begin
    SetGridRowCount(2);
    Cells[0,0]:='idx';
    Cells[1,0]:='FullPath';
    Cells[2,0]:='Filename';
    Cells[3,0]:='Title';
    DefaultRowHeight:=Canvas.TextHeight('0123456789')+5;
  end;

  with WavesOut.Constraints do begin
    MinHeight:=200;
    MaxHeight:=Screen.Height;
    MinWidth:=400;
    MaxWidth:=Screen.Width;
  end;

  InfoLbl.Caption:='Rate='+IntToStr(Main.NowDSoundRate)+'Hz. ';
  InfoLbl.Caption:=InfoLbl.Caption+'ドラッグ＆ドロップして下さい。';

  LoadSkin;

  WavesOut.Show;
  WavesOut.Refresh;
  SizeChangeTimerTimer(Sender);
  LoadMPP(ChangeFileExt(Application.ExeName,'.mpp'));
end;

procedure TWavesOut.encGridDragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
begin
  if isEncoding=True then begin
    Accept:=False;
    exit;
  end;

  Accept:=Main.DragFiles.Enabled;
end;

procedure TWavesOut.encGridDragDrop(Sender, Source: TObject; X,
  Y: Integer);
begin
  if isEncoding=True then exit;

  AddDragFiles(Main.DragFiles);
  encGrid.Refresh;
end;

procedure TWavesOut.AddDragFiles(DragFiles:TDragFiles);
var
  cnt:integer;
  WaveFilename:string;
begin
  if DragFiles.Enabled=False then exit;

  for cnt:=0 to DragFiles.Count-1 do begin
    with DragFiles.DragFile[cnt] do begin
      WaveFilename:=ChangeFileExt(FullPath,'.wav');
      if FullPath[1]='#' then begin
        WaveFilename:=MainINI.WaveNetworkPath+'\'+ExtractFilename(WaveFilename);
        end else begin
        if MainINI.WaveLocalEqualMDXFolder=True then
          WaveFilename:=WaveFilename
          else
          WaveFilename:=MainINI.WaveLocalPath+'\'+ExtractFilename(WaveFilename);
      end;
      ID3:=ConvertTitleToID3(Title);
      ID3.Comment:='dec:MDXWin'+MDXWinVersion+' enc:gogo'+mp3enc.GetVersion;
      ID3.Genre:=MPPSetting.MP3ID3Genre;
      ID3.Year:=MPPSetting.MP3ID3Year;
      ID3.ID:='';
      AddFileList(FullPath,Title,WaveFilename,ID3);
    end;
  end;
end;

procedure TWavesOut.NewFileList;
var
  cnt:integer;
begin
  with encFiles do begin
    Count:=0;
    SetLength(encFile,Count+1);
  end;

  SetGridRowCount(5);
  SizeChangeTimer.Enabled:=True;
  for cnt:=1 to encGrid.RowCount-1 do begin
    encGrid.Cells[0,cnt]:='';
  end;
  encGrid.Refresh;
end;

procedure TWavesOut.AddFileList(const _FullPath,_Title,_WaveFilename:string;const _ID3:TID3);
var
  cnt:integer;
begin
  if encFiles.Count>=65535 then begin
    ShowMessage('65536ファイル以上は登録できません。');
  end;

  with encFiles do begin
    SetLength(encFile,Count+1);
    with encFile[Count] do begin
      FullPath:=_FullPath;
      Title:=_Title;
      WaveFilename:=_WaveFilename;
      ID3:=_ID3;
    end;
    inc(Count);
  end;

  SetGridRowCount(encFiles.Count+1);
  SizeChangeTimer.Enabled:=True;
  for cnt:=1 to encGrid.RowCount-1 do begin
    encGrid.Cells[0,cnt]:=IntToStr(cnt);
  end;
end;

procedure TWavesOut.SortFileList(SortKey:integer;UpDown:boolean);
var
  key1,key2:string;
  c1,c2:integer;
begin
  for c1:=0 to encFiles.Count-2 do begin
    for c2:=c1+1 to encFiles.Count-1 do begin
      case SortKey of
        SortKeyNone: begin
          Key1:='';
          Key2:='';
        end;
        SortKeyFullPath: begin
          key1:=encFiles.encFile[c1].FullPath;
          key2:=encFiles.encFile[c2].FullPath;
        end;
        SortKeyFilename: begin
          key1:=thExtractFilename(encFiles.encFile[c1].FullPath);
          key2:=thExtractFilename(encFiles.encFile[c2].FullPath);
        end;
        SortKeyTitle: begin
          key1:=encFiles.encFile[c1].Title;
          key2:=encFiles.encFile[c2].Title;
        end;
        SortKeyWaveFilename: begin
          key1:=encFiles.encFile[c1].WaveFilename;
          key2:=encFiles.encFile[c2].WaveFilename;
        end;
        else begin
          Key1:='';
          Key2:='';
        end;
      end;
      if UpDown=True then begin
        if key1>key2 then SwapFileList(c1,c2);
        end else begin
        if key1<key2 then SwapFileList(c1,c2);
      end;
    end;
  end;
end;

procedure TWavesOut.SwapFileList(const idx1,idx2:integer);
var
  tmpEncFile:TEncFile;
begin
  if (idx1<0) or (encFiles.Count<=idx1) then exit;
  if (idx2<0) or (encFiles.Count<=idx2) then exit;
  if idx1=idx2 then exit;

  tmpEncFile:=encFiles.encFile[idx1];
  encFiles.encFile[idx1]:=encFiles.encFile[idx2];
  encFiles.encFile[idx2]:=tmpEncFile;
end;

procedure TWavesOut.DeleteFileList(const idx:integer);
var
  cnt:integer;
begin
  if (idx<0) or (encFiles.Count<=idx) then exit;

  if idx<>(encFiles.Count-1) then begin
    for cnt:=idx+1 to encFiles.Count-1 do begin
      encFiles.encFile[cnt-1]:=encFiles.encFile[cnt];
    end;
  end;
  dec(encFiles.Count);

  if encFiles.Count=0 then begin
    SetGridRowCount(5);
    SizeChangeTimer.Enabled:=True;
    for cnt:=1 to encGrid.RowCount-1 do begin
      encGrid.Cells[0,cnt]:='';
    end;
    end else begin
    SetGridRowCount(encFiles.Count+1);
    SizeChangeTimer.Enabled:=True;
  end;
end;

procedure TWavesOut.encGridDblClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  Menu_TestPlayClick(Sender);
end;

procedure TWavesOut.encGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  mes:string;
  idx:integer;
begin
  if (gdFixed in State) then exit;

  with encGrid.Canvas do begin
    Brush.Style:=bsSolid;
    if (gdSelected in State) then begin
      Brush.Color:=CSkin.dwEtcGridSelectBG;
      FillRect(Rect);
      end else begin
      Brush.Color:=CSkin.dwEtcGridBG;
      FillRect(Rect);
    end;

    Pen.Color:=CSkin.dwEtcGridLine;
    if (ARow mod 2)=0 then
      Pen.Style:=psDot
      else
      Pen.Style:=psSolid;
    MoveTo(Rect.Left,Rect.Bottom-1);
    LineTo(Rect.Right,Rect.Bottom-1);

    idx:=ARow-1;
    if idx<0 then exit;
    if idx>=encFiles.Count then exit;

    Font.Color:=CSkin.dwEtcGridText;

    case ACol of
      0: mes:=format('%2.2d',[idx+1]);
      1: mes:=thExtractFilePath(encFiles.encFile[idx].FullPath);
      2: mes:=thExtractFilename(encFiles.encFile[idx].FullPath);
      3: mes:=encFiles.encFile[idx].Title;
    end;

    Brush.Style:=bsClear;
    TextRect(Rect,Rect.Left+4,Rect.Top+1,mes);
  end;
end;

procedure TWavesOut.FormResize(Sender: TObject);
begin
  GripImg.Top:=encPanel.Height-4-GripImg.Height;
  GripImg.Left:=encPanel.Width-4-GripImg.Width;
  SizeChangeTimer.Enabled:=True;
end;

procedure TWavesOut.SizeChangeTimerTimer(Sender: TObject);
begin
  SizeChangeTimer.Enabled:=False;

  SystemBtnPanel.Left:=encPanel.Width-SystemBtnPanel.Width-8;

  InfoLbl.Width:=SystemBtnPanel.Left-InfoLbl.Left;

  PrgBar.Width:=encPanel.Width-8-PrgBar.Left;

  encGrid.Top:=PrgBar.Top+PrgBar.Height+8;
  encGrid.Height:=encPanel.Height-encGrid.Top-16;

  with encGrid do begin
    Left:=8;
    Width:=encPanel.Width-GS_PartsSize-Left-8;
    ColWidths[0]:=20;
    ColWidths[1]:=280*(Width-20) div 600;
    ColWidths[2]:= 80*(Width-20) div 600;
    ColWidths[3]:=240*(Width-20) div 600;
  end;

  GS_WavesOut.ResetPosition;
end;

procedure TWavesOut.GripImgMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MBarFlag:=True;
  MBarX:=X;
  MBarY:=Y;
end;

procedure TWavesOut.GripImgMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if MBarFlag=True then begin
    WavesOut.Width:=WavesOut.Width+(X-MBarX);
    WavesOut.Height:=WavesOut.Height+(Y-MBarY);
  end;
end;

procedure TWavesOut.GripImgMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MBarFlag:=False;
end;

procedure TWavesOut.encPanelMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  DlgDrag:=True;
  Dlgmx:=x;
  Dlgmy:=y;
end;

procedure TWavesOut.encPanelMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if DlgDrag=True then begin
    with WavesOut do begin
      Left:=Left+(X-Dlgmx);
      Top:=Top+(Y-Dlgmy);
    end;
  end;
end;

procedure TWavesOut.encPanelMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  DlgDrag:=False;
end;

procedure TWavesOut.NewLblClick(Sender: TObject);
begin
  if isEncoding=True then exit;

  if MessageDlg('リストを初期化してもよろしいですか？'+CRLF+CRLF+'注意：デコード設定は継承されます。'+CRLF+'クリアするにはSETUPから初期化を行ってください。',mtWarning,[mbOk,mbCancel],0)=mrOk then begin
    NewFileList;
  end;
end;

procedure TWavesOut.encGridMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  col,row:integer;
  idx:integer;
  pos:TPoint;
begin
  if isEncoding=True then exit;

  if Button=mbRight then begin
    encGrid.MouseToCell(x,y,col,row);
    idx:=row-1;
    if idx<0 then exit;
    if idx>=encFiles.Count then exit;
    Grid_MoveIndex(encGrid,row);
    GetCursorPos(pos);
    encGridPopupMenu.Popup(pos.X,pos.Y);
  end;
end;

procedure TWavesOut.Menu_ID3Click(Sender: TObject);
var
  idx:integer;
begin
  if isEncoding=True then exit;

  idx:=Grid_GetIndex(encGrid)-1;
  if idx<0 then exit;
  if idx>=encFiles.Count then exit;

  Application.CreateForm(TID3Edit, ID3Edit);
  ID3Edit.SetCreate;
  ID3Edit.SetID3(encFiles.encFile[idx].ID3);
  if ID3Edit.ShowModal=mrOk then begin
    ID3Edit.GetID3(encFiles.encFile[idx].ID3);
    MPPSetting.MP3ID3Genre:=encFiles.encFile[idx].ID3.Genre;
    MPPSetting.MP3ID3Year:=encFiles.encFile[idx].ID3.Year;
  end;
  ID3Edit.Release;
end;

procedure TWavesOut.Menu_SaveAsClick(Sender: TObject);
var
  idx:integer;
begin
  if isEncoding=True then exit;

  idx:=Grid_GetIndex(encGrid)-1;
  if idx<0 then exit;
  if idx>=encFiles.Count then exit;

  SaveWaveDlg.FileName:=encFiles.encFile[idx].WaveFilename;
  SaveWaveDlg.InitialDir:=ExtractFilePath(SaveWaveDlg.FileName);

  if SaveWaveDlg.Execute=True then begin
    encFiles.encFile[idx].WaveFilename:=ChangeFileExt(SaveWaveDlg.Filename,'.wav');
  end;
end;

procedure TWavesOut.Menu_DeleteClick(Sender: TObject);
var
  idx:integer;
begin
  if isEncoding=True then exit;

  idx:=Grid_GetIndex(encGrid)-1;
  if idx<0 then exit;
  if idx>=encFiles.Count then exit;

  if MessageDlg('ファイル['+encFiles.encFile[idx].FullPath+']'+CRLF+'をリストから削除してもよろしいですか？',mtWarning,[mbOk,mbCancel],0)=mrOk then begin
    DeleteFileList(idx);
    encGrid.Refresh;
  end;
end;

procedure TWavesOut.Menu_TestPlayClick(Sender: TObject);
var
  idx:integer;
begin
  if isEncoding=True then exit;

  idx:=Grid_GetIndex(encGrid)-1;
  if idx<0 then exit;
  if idx>=encFiles.Count then exit;

  MainFileCtl.ExecutePlayFile(encFiles.encFile[idx].FullPath,True);
end;

procedure TWavesOut.Menu_OneDecodeClick(Sender: TObject);
var
  idx:integer;
begin
  if isEncoding=True then exit;

  idx:=Grid_GetIndex(encGrid)-1;
  if idx<0 then exit;
  if idx>=encFiles.Count then exit;

  EncodeStart;
  EncodeProcess(idx);
  EncodeEnd;
end;

function TWavesOut.CheckEncorder:boolean;
begin
  case MPPSetting.FileFormat of
    FileFormat_Wave: Result:=True;
    FileFormat_MP3: begin
      if mp3enc.Enabled=True then begin
        Result:=True;
        end else begin
        Result:=False;
        ShowMessage('MP3出力が指定されましたがgogo.dllが見つかりませんでした。');
      end;
    end;
    FileFormat_Ogg: begin
      if FileExists(StartPath+'oggenc.exe')=True then begin
        Result:=True;
        end else begin
        Result:=False;
        ShowMessage('OggVorbis出力が指定されましたがoggenc.exeが見つかりませんでした。');
      end;
    end;
    else Result:=False;
  end;
end;

procedure TWavesOut.CreateLblClick(Sender: TObject);
var
  idx,idxCount:integer;
  err:boolean;
  Enabled:array of boolean;
  res:TModalResult;
  fn:string;
begin
  if isEncoding=True then begin
    waveenc.Cancelled:=True;
    end else begin
    if CheckEncorder=False then exit;

    EncodeStart;
    idxCount:=encFiles.Count;
    SetLength(Enabled,idxCount);
    err:=False;
    for idx:=0 to idxCount-1 do begin
      Enabled[idx]:=True;
      if err=False then begin
        fn:=encFiles.encFile[idx].WaveFilename;
        case MPPSetting.FileFormat of
          FileFormat_Wave: begin end;
          FileFormat_MP3:  fn:=ChangeFileExt(fn,'.mp3');
          FileFormat_Ogg:  fn:=ChangeFileExt(fn,'.ogg');
        end;
        if FileExists(fn)=True then begin
          Application.CreateForm(TwaveencExist, waveencExist);
          waveencExist.SetPosition(WavesOut);
          waveencExist.SetInfo(idx+1,idxCount,fn,encFiles.encFile[idx].Title);
          res:=waveencExist.ShowModal;
          waveencExist.Release;
          case res of
            mrOK: begin end;
            mrIgnore: Enabled[idx]:=False;
            mrCancel: err:=True;
          end;
        end;
      end;
    end;
    if err=False then begin
      for idx:=0 to idxCount-1 do begin
        if (err=False) and (Enabled[idx]=True) then begin
          Grid_MoveIndex(encGrid,idx+1);
          if EncodeProcess(idx)=False then err:=True;
        end;
      end;
    end;
    EncodeEnd;
  end;
end;

procedure TWavesOut.SetupLblClick(Sender: TObject);
begin
  if isEncoding=True then exit;

  Application.CreateForm(TSetMPP, SetMPP);
  SetMPP.SetCreate(mp3enc.Enabled,mp3enc.GetVersion,MPPSetting);
  if SetMPP.ShowModal=mrOK then begin
    MPPSetting:=SetMPP.MPPSetting;
  end;
  SetMPP.Release;
end;

procedure TWavesOut.CloseLblClick(Sender: TObject);
begin
  if isEncoding=True then exit;

  WavesOut.Visible:=False;
end;

procedure TWavesOut.EncodeStart;
begin
  sdEnd:=True;
  Application.ProcessMessages;

  isEncoding:=True;

  if (VisINI.VisualMode<>VisualModeKeyboard) and (VisINI.VisualMode<>VisualModeSonar) and (VisINI.VisualMode<>VisualModeMDXDis) then begin
    dx3dSetVisible(False);
  end;
  Main.Visible:=False;

  Vis.ClearImage;
  if Main.KDDLoaded=True then begin
    KDD.Visible:=False;
  end;

  Main.RewriteTimer.Enabled:=False;
  Main.goEtcWindowFlag:=True;

  SetShapeLblColor(NewLbl,NewShape,False);
  SetShapeLblColor(LoadLbl,LoadShape,False);
  SetShapeLblColor(SaveLbl,SaveShape,False);
  SetShapeLblColor(CloseLbl,CloseShape,False);
  SetShapeLblColor(CreateLbl,CreateShape,True);
  SetShapeLblColor(SetupLbl,SetupShape,False);
  SetShapeLblColor(SortLbl,SortShape,False);

  CreateLbl.Caption:='STOP';

  waveenc.OnProgress:=WaveProgressEvent;
  if mp3enc.Enabled=True then mp3enc.GogoTea.OnProgress:=GogoTeaProgressEvent;
end;

function TWavesOut.EncodeProcess(idx:integer):boolean;
var
  GogoTeaSetting:TGogoTeaSetting;
begin
  if CheckEncorder=False then begin
    Result:=False;
    exit;
  end;

  if isEncoding=False then begin
    ShowMessage('エンコード開始処理がまだです…？');
    Result:=False;
    exit;
  end;

  InfoLbl.Caption:=Format('[%3d/%3d] ',[idx+1,encFiles.Count]);

  Main.gFileInfo.SetFileInfo(encFiles.encFile[idx].FullPath,False);

  // エンコード開始

  waveenc.StartWaveMode(MPPSetting.PCMRate);
  if waveenc.CreateWave(encFiles.encFile[idx].WaveFilename,MPPSetting.LoopMax,MPPSetting.PCMRate,MPPSetting.TotalVolume,MPPSetting.UseFadeout,MPPSetting.EnableDSP,MPPSetting.StartBlankTime,MPPSetting.EndBlankTime)=True then begin
    Result:=True;
    SetShapeLblColor(CreateLbl,CreateShape,False);
    case MPPSetting.FileFormat of
      FileFormat_Wave: begin end;
      FileFormat_MP3: begin
        GogoTeaSetting:=GetGogoTeaSetting(MPPSetting);
        GogoTeaSetting.SourceFile:=encFiles.encFile[idx].WaveFilename;
        GogoTeaSetting.DestinationFile:=ChangeFileExt(encFiles.encFile[idx].WaveFilename,'.mp3');
        encFiles.encFile[idx].ID3.ID:=char(0)+char(0)+'MDXDecodeID:MDXWin '+MDXWinVersion+char(0)+'MP3EncodeID:gogo'+mp3enc.GetVersion+char(0);
        mp3enc.Execute(GogoTeaSetting,encFiles.encFile[idx].ID3);
      end;
      FileFormat_Ogg: begin
        with encFiles.encFile[idx] do begin
          oggenc.Execute(WaveFilename,MPPSetting,Title,ID3);
        end;
      end;
    end;
    SetShapeLblColor(CreateLbl,CreateShape,True);
    end else begin
    Result:=False;
  end;
  waveenc.EndWaveMode;
end;

procedure TWavesOut.EncodeEnd;
begin
  isEncoding:=False;

  Main.RewriteTimer.Enabled:=True;
  Main.goEtcWindowFlag:=False;

  Main.Visible:=True;
  if (VisINI.VisualMode<>VisualModeKeyboard) and (VisINI.VisualMode<>VisualModeSonar) and (VisINI.VisualMode<>VisualModeMDXDis) then begin
    dx3dSetVisible(True);
  end;
  Application.ProcessMessages;
  WavesOut.Visible:=False;
  WavesOut.Visible:=True;

  waveenc.OnProgress:=nil;
  if mp3enc.Enabled=True then mp3enc.GogoTea.OnProgress:=nil;

  SetShapeLblColor(NewLbl,NewShape,True);
  SetShapeLblColor(LoadLbl,LoadShape,True);
  SetShapeLblColor(SaveLbl,SaveShape,True);
  SetShapeLblColor(CloseLbl,CloseShape,True);
  SetShapeLblColor(CreateLbl,CreateShape,True);
  SetShapeLblColor(SetupLbl,SetupShape,True);
  SetShapeLblColor(SortLbl,SortShape,True);

  CreateLbl.Caption:='Create';

  InfoLbl.Caption:='Wave/MP3/Ogg Processed.';
  PrgBar.Position:=0;
  PrgBar.Max:=0;
end;

procedure TWavesOut.WaveProgressEvent(TotalClock,MesureClock:integer);
begin
  InfoLbl.Caption:=copy(InfoLbl.Caption,1,10)+'CreateWave '+Format('%d/%d',[TotalClock,MesureClock]);
  if TotalClock<MesureClock then begin
    PrgBar.Max:=MesureClock;
    PrgBar.Position:=TotalClock;
  end;
end;

procedure TWavesOut.GogoTeaProgressEvent(Sender:TObject; nowFrames:integer; AllFrames:integer);
begin
  InfoLbl.Caption:=copy(InfoLbl.Caption,1,10)+'CreateMP3 '+Format('%d/%d',[nowFrames,AllFrames]);
  if nowFrames<AllFrames then begin
    PrgBar.Max:=AllFrames;
    PrgBar.Position:=nowFrames;
  end;
end;

procedure TWavesOut.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if isEncoding=True then exit;

  if (Key=VK_F4) and (Shift=[ssAlt]) then begin
    Key:=0;
    CloseLblClick(Sender);
  end;

  if Key=VK_DELETE then begin
    Key:=0;
    Menu_DeleteClick(Sender);
  end;

  if Key=VK_ESCAPE then begin
    Key:=0;
    CloseLblClick(Sender);
  end;
end;

procedure TWavesOut.LoadLblClick(Sender: TObject);
begin
  if isEncoding=True then exit;

  LoadMPPDlg.FileName:=MainINI.WavesLastMPPFilename;
  LoadMPPDlg.InitialDir:=ExtractFilePath(LoadMPPDlg.FileName);

  if LoadMPPDlg.Execute=True then begin
    MainINI.WavesLastMPPFilename:=ChangeFileExt(LoadMPPDlg.Filename,'.mpp');
    LoadMPP(MainINI.WavesLastMPPFilename);
    encGrid.Refresh;
  end;
end;

procedure TWavesOut.SaveLblClick(Sender: TObject);
begin
  if isEncoding=True then exit;

  if encFiles.Count=0 then begin
    ShowMessage('保存すべきMP3リストが空です。');
  end;

  SaveMPPDlg.FileName:=MainINI.WavesLastMPPFilename;
  SaveMPPDlg.InitialDir:=ExtractFilePath(SaveMPPDlg.FileName);

  if SaveMPPDlg.Execute=True then begin
    MainINI.WavesLastMPPFilename:=ChangeFileExt(SaveMPPDlg.Filename,'.mpp');
    SaveMPP(encFiles,MainINI.WavesLastMPPFilename);
  end;
end;

procedure TWavesOut.LoadMPP(MPPFilename:string);
var
  rfb:TReadFileBuf;
  ID:string;
  ini:TINIFile;
begin
  NewFileList;
  ClearMPPSetting(MPPSetting);

  if FileExists(MPPFilename)=False then exit;

  rfb:=TReadFileBuf.Create;
  rfb.Init(MPPFilename);
  rfb.LoadFile;
  ID:=rfb.GetMString;
  rfb.Free;

  if ID<>MPPID01 then begin
    ini:=TINIFile.Create(MPPFilename);
    ID:=ini.ReadString('ID','ID','');
    ini.Free;
  end;

  if ID=MPPID01 then begin
    LoadMPP01(MPPFilename);
    end else begin
    if ID=MPPID02 then begin
      LoadMPP02(MPPFilename);
      end else begin
      ShowMessage('認識できないバージョンのMPPファイルです。');
    end;
  end;

//  Menu_ID3.Enabled:=mp3enc.Enabled;

  if (mp3enc.Enabled=False) and (MPPSetting.FileFormat=FileFormat_MP3) then begin
    MPPSetting.FileFormat:=FileFormat_Wave;
  end;

  InfoLbl.Caption:='ready. ';
end;

procedure TWavesOut.LoadMPP01(MPPFilename:string);
var
  FileCount,cnt:integer;
  rfb:TReadFileBuf;
  encFile:TencFile;
begin
  rfb:=TReadFileBuf.Create;
  rfb.Init(MPPFilename);
  rfb.LoadFile;
  rfb.GetMString; // ID=MPPID01

  rfb.GetVInteger(FileCount);
  for cnt:=0 to FileCount-1 do begin
    with encFile do begin
      rfb.GetVMString(FullPath);
      rfb.GetVMString(Title);
      rfb.GetVMString(WaveFilename);
      with ID3 do begin
        rfb.GetVMString(Title);
        rfb.GetVMString(Artist);
        rfb.GetVMString(Album);
        rfb.GetVMString(Comment);
        rfb.GetVMString(Year);
        rfb.GetVByte(Genre);
        rfb.GetVMString(ID);
      end;
      if ((FullPath<>'') and (WaveFilename<>'')) then AddFileList(FullPath,Title,WaveFilename,ID3);
    end;
  end;

  rfb.Free;
end;

procedure TWavesOut.LoadMPP02(MPPFilename:string);
var
  ini:TINIFile;
  cnt:integer;
  Section:string;
  encFile:TencFile;
  t:dword;
begin
  ini:=TINIFile.Create(MPPFilename);

  ini.ReadString('ID','ID',''); // ID=MPPID02

  with MPPSetting do begin
    Section:='MPPSetting';
    TotalVolume:=ini.ReadInteger(Section,'TotalVolume',TotalVolume);
    LoopMax:=ini.ReadInteger(Section,'LoopMax',LoopMax);
    UseFadeout:=ini.ReadBool(Section,'UseFadeout',UseFadeout);
    EnableDSP:=ini.ReadBool(Section,'EnableDSP',EnableDSP);
    PCMRate:=ini.ReadInteger(Section,'PCMRate',PCMRate);
    StartBlankTime:=ini.ReadInteger(Section,'StartBlankTime',StartBlankTime);
    EndBlankTime:=ini.ReadInteger(Section,'EndBlankTime',EndBlankTime);

    FileFormat:=ini.ReadInteger(Section,'FileFormat',FileFormat);

    MP3BitRate:=ini.ReadInteger(Section,'MP3BitRate',MP3BitRate);
    MP3CPUExtendEnabled:=ini.ReadBool(Section,'MP3CPUExtendEnabled',MP3CPUExtendEnabled);
    MP3Processors:=ini.ReadInteger(Section,'MP3Processors',MP3Processors);
    MP3EncordType:=ini.ReadInteger(Section,'MP3EncordType',MP3EncordType);
    MP3ThreadLevel:=ini.ReadInteger(Section,'MP3ThreadLevel',MP3ThreadLevel);
    MP3LPFEnabled:=ini.ReadBool(Section,'MP3LPFEnabled',MP3LPFEnabled);
    MP3PsyAnalizeEnabled:=ini.ReadBool(Section,'MP3PsyAnalizeEnabled',MP3PsyAnalizeEnabled);
    MP3VBREnabled:=ini.ReadBool(Section,'MP3VBREnabled',MP3VBREnabled);
    MP3VBRQuality:=ini.ReadInteger(Section,'MP3VBRQuality',MP3VBRQuality);
    MP3VBRBitrateEnabled:=ini.ReadBool(Section,'MP3BitrateEnabled',MP3VBRBitrateEnabled);
    MP3VBRBitrateLow:=ini.ReadInteger(Section,'MP3VBRBitrateLow',MP3VBRBitrateLow);
    MP3VBRBitrateHigh:=ini.ReadInteger(Section,'MP3VBRBitrateHigh',MP3VBRBitrateHigh);
    MP3ID3GetTitlePos:=ini.ReadInteger(Section,'MP3ID3GetTitlePos',MP3ID3GetTitlePos);
    MP3ID3Year:=ini.ReadString(Section,'MP3ID3Year',MP3ID3Year);
    MP3ID3Genre:=ini.ReadInteger(Section,'MP3ID3Genre',MP3ID3Genre);

    OggManageMode:=ini.ReadInteger(Section,'OggManageMode',OggManageMode);
    OggQuality:=ini.ReadInteger(Section,'OggQuality',OggQuality);
    OggABRMin:=ini.ReadInteger(Section,'OggABRMin',OggABRMin);
    OggABRNorm:=ini.ReadInteger(Section,'OggABRNorm',OggABRNorm);
    OggABRMax:=ini.ReadInteger(Section,'OggABRMax',OggABRMax);
    OggCBRNorm:=ini.ReadInteger(Section,'OggCBRNorm',OggCBRNorm);
    OggDownmix:=ini.ReadBool(Section,'OggDownmix',OggDownmix);
    OggIgnoreID3:=ini.ReadBool(Section,'OggIgnoreID3',OggIgnoreID3);
    OggAddOption:=ini.ReadString(Section,'OggAddOption',OggAddOption);
  end;

  ini.ReadSections(SectionLst.Items);
  PrgBar.Max:=SectionLst.Count;
  PrgBar.Position:=0;
  t:=GetTickCount;

  for cnt:=0 to SectionLst.Count-1 do begin
    if (GetTickCount-t)>100 then begin
      t:=GetTickCount;
      PrgBar.Position:=cnt;
    end;
    Section:=SectionLst.Items[cnt];
    if copy(Section,1,4)='file' then begin
      with encFile do begin
        FullPath:=ini.ReadString(Section,'FullPath','');
        Title:=ini.ReadString(Section,'Title','');
        WaveFilename:=ini.ReadString(Section,'WaveFilename','');
        with ID3 do begin
          Title:=ini.ReadString(Section,'ID3Title','');
          Artist:=ini.ReadString(Section,'ID3Artist','');
          Album:=ini.ReadString(Section,'ID3Album','');
          Comment:=ini.ReadString(Section,'ID3Comment','');
          Year:=ini.ReadString(Section,'ID3Year','');
          Genre:=byte(ini.ReadInteger(Section,'ID3Genre',0));
          ID:=ini.ReadString(Section,'ID3ID','');
        end;
        if ((FullPath<>'') and (WaveFilename<>'')) then AddFileList(FullPath,Title,WaveFilename,ID3);
      end;
    end;
  end;

  PrgBar.Position:=0;
  PrgBar.Max:=0;

  ini.Free;
end;

procedure TWavesOut.SaveMPP(var encFiles:TencFiles;MPPFilename:string);
var
  ini:TINIFile;
  cnt:integer;
  Section:string;
begin
  DeleteFile(MPPFilename);
  ini:=TINIFile.Create(MPPFilename);

  ini.WriteString('ID','ID',MPPID02);

  with MPPSetting do begin
    Section:='MPPSetting';
    ini.WriteInteger(Section,'TotalVolume',TotalVolume);
    ini.WriteInteger(Section,'LoopMax',LoopMax);
    ini.WriteBool(Section,'UseFadeout',UseFadeout);
    ini.WriteBool(Section,'EnableDSP',EnableDSP);
    ini.WriteInteger(Section,'PCMRate',PCMRate);
    ini.WriteInteger(Section,'StartBlankTime',StartBlankTime);
    ini.WriteInteger(Section,'EndBlankTime',EndBlankTime);

    ini.WriteInteger(Section,'FileFormat',FileFormat);

    ini.WriteInteger(Section,'MP3BitRate',MP3BitRate);
    ini.WriteBool(Section,'MP3CPUExtendEnabled',MP3CPUExtendEnabled);
    ini.WriteInteger(Section,'MP3Processors',MP3Processors);
    ini.WriteInteger(Section,'MP3EncordType',MP3EncordType);
    ini.WriteInteger(Section,'MP3ThreadLevel',MP3ThreadLevel);
    ini.WriteBool(Section,'MP3LPFEnabled',MP3LPFEnabled);
    ini.WriteBool(Section,'MP3PsyAnalizeEnabled',MP3PsyAnalizeEnabled);
    ini.WriteBool(Section,'MP3VBREnabled',MP3VBREnabled);
    ini.WriteInteger(Section,'MP3VBRQuality',MP3VBRQuality);
    ini.WriteBool(Section,'MP3BitrateEnabled',MP3VBRBitrateEnabled);
    ini.WriteInteger(Section,'MP3VBRBitrateLow',MP3VBRBitrateLow);
    ini.WriteInteger(Section,'MP3VBRBitrateHigh',MP3VBRBitrateHigh);
    ini.WriteInteger(Section,'MP3ID3GetTitlePos',MP3ID3GetTitlePos);
    ini.WriteString(Section,'MP3ID3Year',MP3ID3Year);
    ini.WriteInteger(Section,'MP3ID3Genre',MP3ID3Genre);

    ini.WriteInteger(Section,'OggManageMode',OggManageMode);
    ini.WriteInteger(Section,'OggQuality',OggQuality);
    ini.WriteInteger(Section,'OggABRMin',OggABRMin);
    ini.WriteInteger(Section,'OggABRNorm',OggABRNorm);
    ini.WriteInteger(Section,'OggABRMax',OggABRMax);
    ini.WriteInteger(Section,'OggCBRNorm',OggCBRNorm);
    ini.WriteBool(Section,'OggDownmix',OggDownmix);
    ini.WriteBool(Section,'OggIgnoreID3',OggIgnoreID3);
    ini.WriteString(Section,'OggAddOption',OggAddOption);
  end;

  with encFiles do begin
    for cnt:=0 to Count-1 do begin
      Section:='file'+inttostr(cnt);
      with encFile[cnt] do begin
        ini.WriteString(Section,'FullPath',FullPath);
        ini.WriteString(Section,'Title',Title);
        ini.WriteString(Section,'WaveFilename',WaveFilename);
        with ID3 do begin
          ini.WriteString(Section,'ID3Title',Title);
          ini.WriteString(Section,'ID3Artist',Artist);
          ini.WriteString(Section,'ID3Album',Album);
          ini.WriteString(Section,'ID3Comment',Comment);
          ini.WriteString(Section,'ID3Year',Year);
          ini.WriteInteger(Section,'ID3Genre',Genre);
          ini.WriteString(Section,'ID3ID',ID);
        end;
      end;
    end;
  end;

  ini.UpdateFile;
  ini.Free;
end;

procedure TWavesOut.StartupTimerTimer(Sender: TObject);
begin
  StartupTimer.Enabled:=False;
end;

procedure TWavesOut.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  DragAcceptFiles(encGrid.Handle,False);

  SaveMPP(encFiles,ChangeFileExt(Application.ExeName,'.mpp'));
  waveenc.Free;
  waveenc:=nil;
  mp3enc.FreeDLL;
  mp3enc.Free;
  mp3enc:=nil;
  oggenc.FreeDLL;
  oggenc.Free;
  oggenc:=nil;
  GS_WavesOut.Free;
  GS_WavesOut:=nil;

  CanClose:=True;
end;

procedure TWavesOut.FormKeyPress(Sender: TObject; var Key: Char);
var
  lowKey:Char;
begin
  if isEncoding=True then begin
    Key:=char(0);
    exit;
  end;

  lowKey:=lowercase(Key)[1];

  case lowKey of
    '3': begin
      Key:=char(0);
      Menu_ID3Click(Sender);
    end;
    'a': begin
      Key:=char(0);
      Menu_SaveAsClick(Sender);
    end;
    'd': begin
      Key:=char(0);
      Menu_DeleteClick(Sender);
    end;
    'p': begin
      Key:=char(0);
      Menu_TestPlayClick(Sender);
    end;
    't': begin
      Key:=char(0);
      Menu_OneDecodeClick(Sender);
    end;
  end;
end;

procedure TWavesOut.encGridMouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  Handled:=True;
  Grid_MouseWheelViewOnly(encGrid,1,Shift);
end;

procedure TWavesOut.encGridMouseWheelUp(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  Handled:=True;
  Grid_MouseWheelViewOnly(encGrid,-1,Shift);
end;

procedure TWavesOut.Menu_SortFullPathUpClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  SortFileList(SortKeyFullPath,True);
  encGrid.Refresh;
end;

procedure TWavesOut.Menu_SortFilenameUpClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  SortFileList(SortKeyFilename,True);
  encGrid.Refresh;
end;

procedure TWavesOut.Menu_SortWaveFilenameUpClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  SortFileList(SortKeyWaveFilename,True);
  encGrid.Refresh;
end;

procedure TWavesOut.Menu_SortTitleUpClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  SortFileList(SortKeyTitle,True);
  encGrid.Refresh;
end;

procedure TWavesOut.Menu_SortFullPathDownClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  SortFileList(SortKeyFullPath,False);
  encGrid.Refresh;
end;

procedure TWavesOut.Menu_SortFilenameDownClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  SortFileList(SortKeyFilename,False);
  encGrid.Refresh;
end;

procedure TWavesOut.Menu_SortTitleDownClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  SortFileList(SortKeyTitle,False);
  encGrid.Refresh;
end;

procedure TWavesOut.Menu_SortWaveFilenameDownClick(Sender: TObject);
begin
  if isEncoding=True then exit;
  SortFileList(SortKeyWaveFilename,False);
  encGrid.Refresh;
end;

procedure TWavesOut.SortLblMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  pos:TPoint;
begin
  if isEncoding=True then exit;

  GetCursorPos(pos);
  SortPopupMenu.Popup(pos.x,pos.y);
end;

procedure TWavesOut.SetGridRowCount(cnt:integer);
begin
  encGrid.RowCount:=cnt;
  GS_WavesOut.ResetPosition;
end;

end.
