unit fdbtPluginMain;

interface

uses Windows, SysUtils, Classes,
  fdbtPlugin, fdbtPluginUtils, TagEditorLibConsts, TagEditorLibAddinConsts,
  ID3v1, ID3v2, MPEGAudio;



const
  FDBTP_INFO: array[0..FDBT_AUTHOR] of string = (
        '1.1',
        'MP3',
        '.mp3',
        'のらだいこ'
        );


  FDBT_FIELD_LENGTH     = 'length';
  FDBT_FIELD_LAYER      = 'layer';
  FDBT_FIELD_BITRATE    = 'bitrate';
  FDBT_FIELD_SAMPLERATE = 'samplerate';

  FDBT_FIELD_ID3EXIST = 'id3exist';

  FDBTP_FIELDCOUNT = 13;
  FDBTP_FIELDS: array[0..FDBTP_FIELDCOUNT-1] of TTagField = (
        (
        Name:        FDBT_FIELD_TITLE;
        DisplayName: 'タイトル';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    True;      Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_ARTIST;
        DisplayName: 'アーティスト';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    True;      Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_ALBUM;
        DisplayName: 'アルバム';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    True;      Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_TRACK;
        DisplayName: 'トラック';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    True;      Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_DURATION;
        DisplayName: '演奏時間';
        ValueType:   FDBT_VALUE_TYPE_DOUBLE;
        Editable:    False;      Visible: False;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_GENRE;
        DisplayName: 'ジャンル';
        ValueType:   FDBT_VALUE_TYPE_LISTEDIT;
        Editable:    True;      Visible: True;
        Data:        @GenreList;
        ),
        (
        Name:        FDBT_FIELD_YEAR;
        DisplayName: '西暦';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    True;      Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_COMMENT;
        DisplayName: 'コメント';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    True;      Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_LENGTH;
        DisplayName: '時間';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    False;     Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_LAYER;
        DisplayName: 'レイヤー';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    False;     Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_BITRATE;
        DisplayName: 'ビットレート';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    False;     Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_SAMPLERATE;
        DisplayName: 'サンプルレート';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    False;     Visible: True;
        Data:        nil;
        ),
        (
        Name:        FDBT_FIELD_ID3EXIST;
        DisplayName: 'ID3';
        ValueType:   FDBT_VALUE_TYPE_STRING;
        Editable:    False;     Visible: True;
        Data:        nil;
        )
        );


type

TFdbtPluginMain = class(TFdbtPlugin)
private
  FAddinMenu: TAddinMenu;
  FGetTrackDataInfo: TGetTrackDataInfo;
public
  TrackTools: TTrackDataInfo;
  function Initialize(info: PFdbtPluginInitInfo): integer; override;
  function GetLibInfo(InfoNo: Integer; Buffer: PChar; Size: Integer): Integer; override;
  function ShowConfig: integer; override;
  function GetTagInfo(FileName: PWideChar; Tag: PTagInfo; Size: integer): integer; override;
  function SetTagInfo(FileName: PWideChar; Tag: PTagInfo): integer; override;
  function GetTagFieldInfo(fl: PTagFieldList; size: integer): integer; override;

  function AddinMenu(place: integer; Identify: PChar; DisplayName: PChar; ProcExe: TAddinProc; ImageType: integer; Image: cardinal): integer;
  function GetTrackDataInfo: TTrackDataInfo;
end;


implementation

uses id3config;


function TFdbtPluginMain.Initialize(info: PFdbtPluginInitInfo): integer;
begin
  inherited Initialize(info);
  @FAddinMenu:=InitInfo.GetService('AddinMenu');
  @FGetTrackDataInfo:=InitInfo.GetService('GetTrackDataInfo');

  TrackTools:=GetTrackDataInfo();

  AddinMenu(FDBT_ADDIN_PLACE_SETTING, 'miSetID3v1v2','ID3v1/v2', Configure, FDBT_IMAGE_NONE, 0);

  Result:=FDBT_SUCCESS;
end;


function TFdbtPluginMain.GetLibInfo(InfoNo: Integer; Buffer: PChar; Size: Integer): Integer;
var
  PlugInfo : string;
begin
  PlugInfo:=FDBTP_INFO[InfoNo];
  lstrcpyn(Buffer, PChar(PlugInfo), Size);
  Result:=Length(Buffer);
end;

function TFdbtPluginMain.ShowConfig: integer;
begin
  Configure;
  Result:=FDBT_SUCCESS;
end;

function TFdbtPluginMain.GetTagInfo(FileName: PWideChar; Tag: PTagInfo; Size: integer): integer;
var
  mpga: TMPEGaudio;
  v1: TID3v1;
  v2: TID3v2;
  sec: integer;
  durstr,s: string;
begin
  mpga:=TMPEGaudio.Create;
  mpga.ReadFromFile(FileName);

  if mpga.Valid then
  begin
    v1:=mpga.ID3v1;
    v2:=mpga.ID3v2;

    if v2.Exists then
    begin

      SetTagValue(tag^[0], FDBT_FIELD_TITLE,    v2.Title);
      SetTagValue(tag^[1], FDBT_FIELD_ARTIST,   v2.Artist);
      SetTagValue(tag^[2], FDBT_FIELD_ALBUM,    v2.Album);
      SetTagValue(tag^[3], FDBT_FIELD_TRACK,    v2.TrackString);
      SetTagValue(tag^[4], FDBT_FIELD_GENRE,    v2.Genre);
      SetTagValue(tag^[5], FDBT_FIELD_YEAR,     v2.Year);
      SetTagValue(tag^[6], FDBT_FIELD_COMMENT,  v2.Comment);

    end else
    if v1.Exists then
    begin

      SetTagValue(tag^[0], FDBT_FIELD_TITLE,    v1.Title);
      SetTagValue(tag^[1], FDBT_FIELD_ARTIST,   v1.Artist);
      SetTagValue(tag^[2], FDBT_FIELD_ALBUM,    v1.Album);
      SetTagValue(tag^[3], FDBT_FIELD_TRACK,    v1.TrackString);
      SetTagValue(tag^[4], FDBT_FIELD_GENRE,    v1.Genre);
      SetTagValue(tag^[5], FDBT_FIELD_YEAR,     v1.Year);
      SetTagValue(tag^[6], FDBT_FIELD_COMMENT,  v1.Comment);

    end;

    sec:=round(mpga.Duration);
    durstr:=StringReplace(format('%2d:%2d', [sec div 60, sec mod 60]), ' ', '0', [rfReplaceAll]);
    SetTagValue(tag^[7],  FDBT_FIELD_DURATION,   mpga.Duration);
    SetTagValue(tag^[8],  FDBT_FIELD_LENGTH,     durstr);
    SetTagValue(tag^[9],  FDBT_FIELD_LAYER,      mpga.Version+mpga.Layer);
    SetTagValue(tag^[10], FDBT_FIELD_BITRATE,    IntToStr(mpga.BitRate)+' kbit/s');
    SetTagValue(tag^[11], FDBT_FIELD_SAMPLERATE, IntToStr(mpga.SampleRate)+' hz');

    if mpga.ID3v1.Exists then
      if mpga.ID3v2.Exists then
        s:='ID3v1/v2'
      else
        s:='ID3v1'
    else
    if mpga.ID3v2.Exists then  
      s:='ID3v2'
    else
      s:='none';
    SetTagValue(tag^[12], FDBT_FIELD_ID3EXIST, s);

    Result:=FDBTP_FIELDCOUNT;
  end else
    Result:=0;

  mpga.Free;
end;

function TFdbtPluginMain.SetTagInfo(FileName: PWideChar; Tag: PTagInfo): integer;

var
  mpga: TMPEGaudio;
  v1: TID3v1;
  v2: TID3v2;
  i, c, len: integer;
  fld, v: string;
begin
  Result:=FDBT_SUCCESS;
  
  mpga:=TMPEGaudio.Create;
  mpga.ReadFromFile(FileName);

  if mpga.Valid then
  begin
    v1:=mpga.ID3v1;
    v2:=mpga.ID3v2;

    c:=Length(Tag^);
    len:=0;

    if Config.SaveType in [ID3_v2, ID3_Auto, ID3_Both] then
    begin

      for i:=0 to c-1 do
      begin
        fld := Tag^[i].Field;
        v   := Value2String(Tag^[i].Value);

        if fld=FDBT_FIELD_TITLE   then v2.Title   := v;
        if fld=FDBT_FIELD_ARTIST  then v2.Artist  := v;
        if fld=FDBT_FIELD_ALBUM   then v2.Album   := v;
        if fld=FDBT_FIELD_TRACK   then v2.Track   := StrToIntDef(v, 0);
        if fld=FDBT_FIELD_GENRE   then v2.Genre   := v;
        if fld=FDBT_FIELD_YEAR    then v2.Year    := v;
        if fld=FDBT_FIELD_COMMENT then v2.Comment := v;

        if len<length(v) then len := Length(v);
      end;

      // 書き込み
      if (Config.SaveType in [ID3_v2, ID3_Both]) or ((Config.SaveType = ID3_Auto)and(len>=30)) then
        if not v2.SaveToFile(FileName) then
          Result:=FDBT_INTERNAL_ERROR;
      if (Config.SaveType = ID3_Auto)and(len<30) then
        v2.RemoveFromFile(FileName);
    end;

    if (Result=FDBT_SUCCESS) and
       ((Config.SaveType in [ID3_v1, ID3_Both]) or ((Config.SaveType = ID3_Auto)and(len<30))) then
    begin

      for i:=0 to c-1 do
      begin
        fld := Tag^[i].Field;
        v   := Value2String(Tag^[i].Value);

        if fld=FDBT_FIELD_TITLE   then v1.Title   := v;
        if fld=FDBT_FIELD_ARTIST  then v1.Artist  := v;
        if fld=FDBT_FIELD_ALBUM   then v1.Album   := v;
        if fld=FDBT_FIELD_TRACK   then v1.Track   := StrToIntDef(v, 0);
        if fld=FDBT_FIELD_GENRE   then v1.Genre   := v;
        if fld=FDBT_FIELD_YEAR    then v1.Year    := v;
        if fld=FDBT_FIELD_COMMENT then v1.Comment := v;

      end;

      // 書き込み
      if not v1.SaveToFile(FileName) then
        Result:=FDBT_INTERNAL_ERROR;
    end;

    if Config.SaveType = ID3_v2 then v1.RemoveFromFile(FileName);
    if Config.SaveType = ID3_v1 then v2.RemoveFromFile(FileName);

  end else
    Result:=FDBT_INTERNAL_ERROR;

  mpga.Free;
end;

function TFdbtPluginMain.GetTagFieldInfo(fl: PTagFieldList; size: integer): integer;
var
  i: integer;
begin
  for i:=0 to FDBTP_FIELDCOUNT-1 do
    fl^[i]:=FDBTP_FIELDS[i];

  Result:=FDBTP_FIELDCOUNT;
end;

function TFdbtPluginMain.AddinMenu(place: integer; Identify: PChar; DisplayName: PChar; ProcExe: TAddinProc; ImageType: integer; Image: cardinal): integer;
begin
  if Assigned(FAddinMenu) then
    Result:=FAddinMenu(place, Identify, DisplayName, ProcExe, ImageType, Image)
  else
    Result:=FDBT_NOTIMPLEMENTED;
end;

function TFdbtPluginMain.GetTrackDataInfo: TTrackDataInfo;
begin
  if Assigned(FGetTrackDataInfo) then Result:=FGetTrackDataInfo();
end;



end.
