{ KOL MCK } // Do not remove this line!
{$DEFINE KOL_MCK}

Unit Main;

interface

{$IFDEF KOL_MCK}
uses Windows, Messages, KOL, KOLBAPFileBrowser, KOLBAPDriveBox, AudioVerify {$IFNDEF KOL_MCK}, mirror, Classes,  Controls, mckBAPFileBrowser, mckCtrls, Graphics,  mckBAPDriveBox,  mckEcmListEdit,  MCKmdvXLGrid,  MCKmdvToolTip,  MCKATL {$ENDIF}, ATLCommon;
{$ELSE}
{$I uses.inc}
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, mirror;
{$ENDIF}

type
  {$IFDEF KOL_MCK}
  {$I MCKfakeClasses.inc}
  {$IFDEF KOLCLASSES} {$I MainFormclass.inc} {$ELSE OBJECTS} PMainForm = ^TMainForm; {$ENDIF CLASSES/OBJECTS}
  {$IFDEF KOLCLASSES}{$I TMainForm.inc}{$ELSE} TMainForm = object(TObj) {$ENDIF}
    Form: PControl;
  {$ELSE not_KOL_MCK}
  TMainForm = class(TForm)
  {$ENDIF KOL_MCK}
    KOLProject: TKOLProject;
    Panel1: TKOLPanel;
    BAPFileBrowser: TKOLBAPFileBrowser;
    BAPDriveBox1: TKOLBAPDriveBox;
    Panel2: TKOLPanel;
    Label10: TKOLLabel;
    Panel3: TKOLPanel;
    sbTags: TKOLScrollBox;
    lbFormatInfo: TKOLListBox;
    KOLForm: TKOLForm;
    btnSave: TKOLButton;
    btnShowMyTeg: TKOLButton;
    btnDelMyTeg: TKOLButton;
    btnAddMyTeg: TKOLButton;
    AudioVerify: TAudioVerify;
    procedure KOLFormFormCreate(Sender: PObj);
    procedure btnSaveClick(Sender: PObj);
    procedure BAPDriveBox1ChangeDrive(Sender: PControl; Drive: String;
      const ReadErr: Boolean; var Retry: Boolean);
    procedure btnMyTegClick(Sender: PObj);
    procedure BAPFileBrowserSelFile(Sender: PControl; FileName: String;
      const Dir: Boolean; Attr: PFindFileData);
  private
    FFileName: String;
    FAudioVendor: TAudioVendor;
    procedure LoadFile(const FileName: String);
    procedure Clear;
    procedure AddRow(Text_1, Text_2: String; const Data_1, Data_2: Integer;
      AFontColor: TColor);
    procedure FillTag(ATag: PTagInfo);
    function ReadAudio(AReader: Pointer): Boolean;
  public
    { Public declarations }
  end;

var
  MainForm {$IFDEF KOL_MCK} : PMainForm {$ELSE} : TMainForm {$ENDIF} ;

{$IFDEF KOL_MCK}
procedure NewMainForm( var Result: PMainForm; AParent: PControl );
{$ENDIF}

implementation

uses ATLLib, ATLConstEx,

     TagID3v1, TagID3v1Lyrics, TagID3v2, TagAPE, TagVorbis, TagTwinVQ, TagWMA, TagMp4,

     AudioMPEG, AudioWMA, AudioMP4,

     AudioAC3, AudioAAC, AudioOptimFROG, AudioTTA, AudioDTS, AudioFLAC, AudioWAV,
     AudioTwinVQ, AudioCDATrack, AudioOgg, AudioWAVPack, AudioMonkey, AudioMPEGplus;

{$IFNDEF KOL_MCK} {$R *.DFM} {$ENDIF}

{$IFDEF KOL_MCK}
{$I Main_1.inc}
{$ENDIF}

type TReader = function: PAudioInfo;

const Audio: array [TAudioVendor] of Pointer = (@NewAudioWav, @NewAudioWAVPack, @NewAudioMonkey, @NewAudioOGG, @NewAudioAC3, @NewAudioAAC, @NewAudioDTS, @NewAudioTTA, @NewAudioWMA, @NewAudioOptimFrog, @NewAudioFlac, @NewAudioTwinVQ, @NewAudioCDATrack, @NewAudioMPEG, @NewAudioMPEGplus, @NewAudioMP4, nil);

procedure TMainForm.AddRow(Text_1, Text_2: String; const Data_1, Data_2: Integer; AFontColor: TColor);
var RowPanel, ColPanel, EditBox, ComboBox: PControl;
    i: Integer;
begin
    RowPanel:= NewPanel(sbTags, esLowered).SetPosition(1, (sbTags.ChildCount-1)*18).SetSize(sbTags.Width-30, 18);
    RowPanel.Border:= -1;
    RowPanel.Tag:= Data_1;

    ColPanel:= NewPanel(RowPanel, esLowered).SetAlign(caLeft).SetSize(180, 0);
    ColPanel.TextAlign:= taLeft;
    ColPanel.Border:= 2;
    ColPanel.Caption:= Text_1;
    ColPanel.Tag:= Data_1;
    if AFontColor = clWindowText then ColPanel.TextAlign:= taRight;
    ColPanel.Font.Color:= AFontColor;
    if AFontColor = clRed then ColPanel.Font.FontStyle:= [fsBold];

    if Data_2 = Integer(etGenre) then begin
      ComboBox:= NewComboBox(RowPanel, [coNoIntegralHeight]).SetAlign(caClient);
      ComboBox.Tag:= Data_2+1;
      ComboBox.Color := clWindow;
      ComboBox.Add('');
      for i:= 0 to MusicGenreCount-1 do begin
        ComboBox.Add(MusicGenre[i]);
      end;
      ComboBox.Text:= Text_2;
    end
    else
      if AFontColor = clWindowText then begin
        EditBox:= NewEditBox(RowPanel, []).SetAlign(caClient);
        EditBox.Tag:= Data_2+1;
        EditBox.Color := clWindow;
        EditBox.Text:= Text_2;
        EditBox.Font.Color:= AFontColor;
      end
      else begin
        EditBox:= NewCheckbox(RowPanel, Text_2).SetAlign(caClient);
        EditBox.Tag:= 1000;
        EditBox.Checked:= Boolean(Data_2);
      end;
end;

procedure TMainForm.FillTag(ATag: PTagInfo);
var Tags: TEasyTags;
begin
    AddRow(GetTagVendorName(ATag.TagVendor), '        Tag size:  ' + Int2Str(ATag.TagSize) + ' bytes', Integer(ATag.TagVendor), Integer(ATag.Exists), clRed);
    for Tags:= Low(TEasyTags) to High(TEasyTags) do
      if Tags in ATag.ExistsTags then
        AddRow(GetTagsNames(Tags), ATag.Tags[Tags], Integer(ATag.TagVendor), Integer(Tags), clWindowText);
    if ATag.TagVendor = tID3v1 then
       FillTag(PTagID3v1(ATag).Lyrics);
    sbTags.Invalidate;
end;

function TMainForm.ReadAudio(AReader: Pointer): Boolean;
  function GetProps(AudioInfo: PAudioInfo; Index: TAudioProps): String;
  begin
      Result:= '';
      case Index of
        apSampleRate: Result:= Int2Str(AudioInfo.SampleRate) + ' Hz';
        apBitrate: Result:= Int2Str(AudioInfo.Bitrate) + ' kbps';
        apChannels: Result:= Int2Str(AudioInfo.Channels);
        apBits: Result:= Int2Str(AudioInfo.Bits) + ' bit';
        apSamples: Result:= Int2Str(AudioInfo.Samples);
        apDuration: Result:= Sec2Time(AudioInfo.Duration);
        apRatio: Result:= Int2Str(Round(AudioInfo.Ratio)) + ' %';
        apBitrateType: if AudioInfo.BitrateType = btCBR then Result:= 'CBR' else
                         if AudioInfo.BitrateType = btVBR then Result:= 'VBR';
      end;
  end;
var AudioInfo: PAudioInfo;
    Props: TAudioProps;
    Tags: TTagVendor;
    Vendor: String;
    i: Integer;
begin
    AudioInfo:= TReader(AReader);
    try
      Result:= AudioInfo.ReadFromFile(FFileName) and AudioInfo.Valid;
      if not Result then Exit;

      Vendor:= GetAudioVendorName(AudioInfo.AudioVendor);
      Form.Caption:= 'ATL DEMO -' + ExtractFileName(FFileName) + ' ('+Vendor+')';
      lbFormatInfo.Add('Audio:  ' + Vendor);

      {$IFDEF USE_OtherAudioProps}
      for i:= 0 to AudioInfo.OtherProps.Count - 1 do begin
         Vendor:= AudioInfo.OtherProps.Items[i];
         StrReplace(Vendor, '=', ':  ');
         lbFormatInfo.Add(Vendor);
      end;
      {$ENDIF}

      lbFormatInfo.Add('ChannelMode:  ' + AudioInfo.ChannelMode);

      for Props:= Low(TAudioProps) to High(TAudioProps) do begin
        if Props in AudioInfo.ExistsProps then
          lbFormatInfo.Add(GetAudioPropsNames(Props) + ':  ' + GetProps(AudioInfo, Props));
      end;

      lbFormatInfo.Add('FileSize:  ' + Int2Str(AudioInfo.FileSize) + ' bytes');

      for Tags:= Low(TTagVendor) to High(TTagVendor) do
        if Tags in AudioInfo.TagExists then
          FillTag(AudioInfo.TagInfo[Tags]);

    finally
      AudioInfo.Free;
    end;
end;

procedure TMainForm.LoadFile(const FileName: String);
var i: TAudioVendor;
begin
    FAudioVendor:= Ext2AudioVendor(ExtractFileExt(FileName));
    if FAudioVendor = aUnknown then Exit;
    if ReadAudio(Audio[FAudioVendor]) then Exit;

    for i:= Low(TAudioVendor) to Pred(High(TAudioVendor)) do
      if (i<>FAudioVendor) and ReadAudio(Audio[i]) then begin
        FAudioVendor:= i;
        Exit;
      end;
    FAudioVendor:= aUnknown;
end;

procedure TMainForm.btnSaveClick(Sender: PObj);
  function FillTags(ATag: PTagInfo): Boolean;
  var i: Integer;
  begin
      Result:= True;
      for i:= 0 to sbTags.ChildCount - 1 do begin
        if ATag.TagVendor = TTagVendor(sbTags.Children[i].Tag) then begin
          case sbTags.Children[i].Children[1].Tag of
            1000: begin
              Result:= sbTags.Children[i].Children[1].Checked;
  //            if not Result then Exit;
            end;
            0:;
            else begin
              if Result then ATag.Tags[TEasyTags(sbTags.Children[i].Children[1].Tag-1)]:= sbTags.Children[i].Children[1].Text
              else ATag.Tags[TEasyTags(sbTags.Children[i].Children[1].Tag-1)]:= '';
            end;
          end;
        end;
      end;
  end;
var AudioInfo: PAudioInfo;
    Tags: TTagVendor;
begin
    if (FFileName = '') or (FAudioVendor = aUnknown) then Exit;
    AudioInfo:= TReader(Audio[FAudioVendor]);
    if not AudioInfo.ReadFromFile(FFileName) and AudioInfo.Valid then Exit;
    for Tags:= Low(TTagVendor) to High(TTagVendor) do
      if Tags in AudioInfo.TagExists then begin
        if FillTags(AudioInfo.TagInfo[Tags]) then begin
          if Tags = tID3v1 then
            if not FillTags(PTagID3v1(AudioInfo.TagInfo[Tags]).Lyrics) then PTagID3v1(AudioInfo.TagInfo[Tags]).Lyrics.RemoveFromFile(FFileName);
          AudioInfo.TagInfo[Tags].SaveToFile(FFileName);
        end
        else AudioInfo.TagInfo[Tags].RemoveFromFile(FFileName);
      end;
//        AudioInfo.TagInfo[Tags].SaveToFile(FFileName);
    AudioInfo.Free;
end;

procedure TMainForm.Clear;
var i: Integer;
begin
    for i:= sbTags.ChildCount - 1 downto 0 do sbTags.Children[i].Free;
    lbFormatInfo.Clear;
    FFileName:= ''; FAudioVendor:= aUnknown;
end;

procedure TMainForm.BAPFileBrowserSelFile(Sender: PControl; FileName: String; const Dir: Boolean; Attr: PFindFileData);
begin
    Clear;
    if Dir then Exit;

    FFileName:= BAPFileBrowser.Directory+FileName;
    LoadFile(FFileName);
end;

procedure TMainForm.KOLFormFormCreate(Sender: PObj);
begin
    FAudioVendor:= aUnknown;
    Label10.Caption:= 'Tags: ID3v1, ID3v1 Lyrics, ID3v2, APE, Vorbis, TwinVQ, WMA, ExWMA'#13#10+
                      'Audio: AC3, WMA, AAC, OptimFROG, TTA, DTS, FLAC, TwinVQ, CDATrack,'#13#10+
                      '           Ogg (Vorbis, Speex), WAV, WAVPack, Monkey, MPEG, MPEGplus';

    lbFormatInfo.Perform(LB_SETCOLUMNWIDTH, 250, 0);
    BAPFileBrowser.FileFilter:= GetAudioFileMaskAll;
    BAPFileBrowser.Refresh;
end;

procedure TMainForm.BAPDriveBox1ChangeDrive(Sender: PControl;
  Drive: String; const ReadErr: Boolean; var Retry: Boolean);
begin
    BAPFileBrowser.Directory:= Drive;
end;

procedure TMainForm.btnMyTegClick(Sender: PObj);              
var TagID3v2: PTagID3v2;
    i: Integer;
    S: String;
begin
    if AudioVerify.VerifyAudio(FFileName) and AudioVerify.Valid then begin
      S:= '';
      if tID3v2 in AudioVerify.AudioInfo.TagExists then begin
        TagID3v2:= Pointer(AudioVerify.AudioInfo.TagInfo[tID3v2]);
        case Sender.Tag of
          1: begin
            TagID3v2.SetTagEx('MyTg', 'ÝÒÎ ÎÔÈÃÅÍÍÛÉ ÑÎÁÑÒÂÅÍÍÛÉ ÒÅÃ!!!!!!!!');
            TagID3v2.SaveToFile(FFileName);
          end;
          2:
            for i:= 0 to TagID3v2.TagExCount-1 do begin
              if TagID3v2.TagEx[i].ID = 'MyTg' then S:= S + '----------- MyTeg -----------'+#13#10;
              S:= S + TagID3v2.TagEx[i].ID + ':   ' + TagID3v2.TagExString[i]+#13#10;
              if TagID3v2.TagEx[i].ID = 'MyTg' then S:= S + '----------- MyTeg -----------'+#13#10;
            end;
          3: begin
            for i:= TagID3v2.TagExCount-1 downto 0 do
              if TagID3v2.TagEx[i].ID = 'MyTg' then begin
                TagID3v2.DeleteTag(i);
                Break; //Ìîæíî óáðàòü äëÿ ïðîñìîòðà âñåõ òåãîâ.
              end;
            TagID3v2.SaveToFile(FFileName);
          end;
        end;
      end;
      if Sender.Tag = 2 then ShowMessage(S);
    end;
end;

end.



