{}

function GetStatusText(status:integer;toCList:boolean=false):PWideChar;
begin
  case status of
    RD_STATUS_PAUSED : result:='paused';
    RD_STATUS_STOPPED: if toCList then result:=nil else result:='stopped';
    RD_STATUS_CONNECT: result:='connecting';
    RD_STATUS_ABORT  : result:='aborting';
    RD_STATUS_PLAYING: if toCList then result:=nil else result:='playing';
  else
    result:=nil;
  end;
end;

procedure ConstructMsg(artist,title:PWideChar;status:integer=-1);
var
  buf:PWideChar;
  tstrlen,astrlen,statuslen:integer;
  sstatus:PWideChar;
  p:pWideChar;
begin
  astrlen:=StrLenW(artist);

  tstrlen:=0;
  // if need to remove duplicate
  if (title<>nil) and (title^<>#0) then
  begin
    if (astrlen=0) or (StrCmpW(artist,title)<>0) then
      tstrlen:=StrLenW(title);
  end;
  if (astrlen>0) and (tstrlen>0) then
    inc(tstrlen,3);

  statuslen:=0;
  if status>=0 then
  begin
    sstatus:=TranslateW(GetStatusText(status,true));
    if sstatus<>nil then
      statuslen:=StrLenW(sstatus)+3;
  end
  else
    sstatus:=nil;

  if (astrlen+tstrlen+statuslen)>0 then
  begin
    mGetMem(buf,(astrlen+tstrlen+statuslen+1)*SizeOf(WideChar));
    p:=buf;
    if astrlen>0 then
      p:=StrCopyEW(p,artist);

    if tstrlen>0 then
    begin
      if astrlen>0 then
      begin
        p^:=' '; inc(p);
        p^:='-'; inc(p);
        p^:=' '; inc(p);
      end;
      p:=StrCopyEW(p,title);
    end;

    if statuslen>0 then
    begin
      p^:=' '; inc(p);
      p^:='('; inc(p);
      p:=StrCopyEW(p,sstatus);
      p^:=')'; inc(p);
      p^:=#0;
    end;

    DBWriteUnicode(ActiveContact,strCList,optStatusMsg,buf);
    mFreeMem(buf);
  end
  else
    DBDeleteSetting(ActiveContact,strCList,optStatusMsg);
end;

{$IFDEF Debug}
procedure log(a,b:lparam);
var
  f:thandle;
  buf:array [0..31] of ansichar;
  p:pansichar;
begin
  f:=Append(pansichar('mradio.log'));
  p:=IntToStr(buf,a); BlockWrite(f,p^,StrLen(p));
  p:=#13#10; BlockWrite(f,p^,StrLen(p));
  p:=IntToStr(buf,b); BlockWrite(f,p^,StrLen(p));
  p:=#13#10; BlockWrite(f,p^,StrLen(p));
  p:=#13#10; BlockWrite(f,p^,StrLen(p));
  CloseHandle(f);
end;
{$ENDIF}

function ControlCenter(code:WPARAM;arg:LPARAM):int_ptr; cdecl;
const
  PlayStatus:int_ptr=RD_STATUS_NOSTATION;
  doRecord:boolean=false;
var
  tmpbuf,buf1:array [0..MAX_PATH-1] of WideChar;
  plFile:pWideChar;
  plLocal:boolean;
  artist,title:pWideChar;
begin
  result:=0;
{$IFDEF Debug}
  log(code,arg);
{$ENDIF}
  case code of
    MRC_PLAY : begin
      // play new station?
      if arg<>0 then
      begin
        ActiveURLw:=DBReadUnicode(arg,PluginName,optStationURL);
        // no URL for this contact
        if (ActiveURLw=nil) or (ActiveURLw^=#0) then exit;

        ActiveContact:=arg;
        RemoteSong:=StrPosW(ActiveURLw,'://')<>nil;

        if isPlaylist(ActiveURLw)<>0 then
        begin

          if RemoteSong then
          begin
            GetTempPathW(MAX_PATH,tmpbuf);
            GetTempFileNameW(tmpbuf,'mr',GetCurrentTime,buf1);
            if not GetFile(ActiveURLw,buf1,hNetLib) then
            begin
              exit;
            end;
            plFile:=@buf1;
            plLocal:=false;
          end
          else
          begin
            plFile:=ActiveURLw;
            plLocal:=true;
          end;

          plist:=CreatePlaylist(plFile);
          if not plLocal then
            DeleteFileW(plFile);

          if plist<>nil then
          begin
            if plist.GetCount=0 then
            begin
              plist.Free;
              plist:=nil;
              ActiveContact:=0;
              exit;
            end;
            plist.Shuffle:=doShuffle<>BST_UNCHECKED;

            if not plist.Shuffle then
            begin
              if PlayFirst=BST_UNCHECKED then
                plist.Track:=DBReadWord(ActiveContact,PluginName,optCurElement);
            end;

            mFreeMem(ActiveURLw);
            ActiveURLw:=plist.GetSong;
          end;
          RemoteSong:=StrPosW(ActiveURLw,'://')<>nil; // coz activeuRLw can be changed
        end
        else
          plist:=nil;

        if (ActiveURLw<>nil) and (ActiveURLw^<>#0) then
        begin
          if RemoteSong then
          begin
            if GetWorkOfflineStatus<>0 then
            begin
              BassError('Can''t connect to net. Please, clear ''Work offline'' option in Internet settings');
              ControlCenter(MRC_STATUS,RD_STATUS_NOSTATION);
              exit;
            end;
          end;
          ControlCenter(MRC_STATUS,RD_STATUS_NEWSTATION);
          if Assigned(plist) then
            ControlCenter(MRC_STATUS,RD_STATUS_CONNECT);
          mir_forkthread(@OpenURL,ActiveURLw);
        end;
      end
      // play current from start
      else if chan<>0 then
      begin
        BASS_ChannelPlay(chan,true);
        code:=MRC_STATUS;
        arg :=RD_STATUS_PLAYING;
      end
      // play playlist entry?
      else if Assigned(plist) and (ActiveURLw<>nil) and (ActiveURLw^<>#0) then
      begin
        mir_forkthread(@OpenURL,ActiveURLw);
      end;
    end;

    MRC_RECORD: begin
      if arg=LPARAM(-1) then
        result:=ord(doRecord)
      else
      begin
        case arg of
          1: doRecord:=true;  // force start
          2: doRecord:=false; // force stop
        else
          doRecord:=not doRecord;
        end;
        result:=ord(doRecord);

        code:=MRC_STATUS;
        arg :=RD_STATUS_RECORD+(result shl 16);
      end;
    end;

    MRC_PAUSE: begin
      if chan<>0 then
      begin
        case ControlCenter(MRC_STATUS,RD_STATUS_GET) of
          RD_STATUS_PLAYING: begin
            BASS_ChannelPause(chan);
            arg:=1;
          end;
          RD_STATUS_PAUSED: begin
            BASS_ChannelPlay(chan,false);
            arg:=0;
          end;
        end;
        code:=MRC_STATUS;
        arg :=RD_STATUS_PAUSED+(arg shl 16);
      end
      else
      begin
        ActiveContact:=LoadContact(PluginName,optLastStn);
        if ActiveContact<>0 then
          ControlCenter(MRC_PLAY,ActiveContact);
      end;
    end;

    MRC_STOP: begin
      ControlCenter(MRC_RECORD,2);

      code:=MRC_STATUS;
      // stop playlist track but not station
      if Assigned(plist) and (arg=0) then
      begin
        if chan<>0 then
          BASS_ChannelStop(chan);

        arg:=RD_STATUS_STOPPED;
      end
      else // forced or "normal" stop
      begin
        if Assigned(plist) then
        begin
          DBWriteWord(ActiveContact,PluginName,optCurElement,plist.Track);
          plist.Free;
          plist:=nil;
        end;
        ControlCenter(MRC_STATUS,RD_STATUS_STOPPED);
        // Save station for next autoplay
        SaveContact(ActiveContact,PluginName,optLastStn);
        StopStation;

        arg:=RD_STATUS_NOSTATION;
      end;
    end;

    MRC_MUTE: begin
      CallService(MS_RADIO_MUTE,0,arg);
      code:=MRC_STATUS;
      arg :=RD_STATUS_MUTED;
    end;

    MRC_NEXT: begin
      if Assigned(plist) then
      begin
        StopStation;
        ActiveURLw:=plist.Next;
        ControlCenter(MRC_PLAY,0);
      end;
    end;

    MRC_PREV: begin
      if Assigned(plist) then
      begin
        StopStation;
        ActiveURLw:=plist.Previous;
        ControlCenter(MRC_PLAY,0)
      end;
    end;

    MRC_SEEK: begin
      if not RemoteSong and (chan<>0) then
      begin
        if integer(arg)=-1 then // get position
        begin
          result:=trunc(BASS_ChannelBytes2Seconds(chan,BASS_ChannelGetPosition(chan,BASS_POS_BYTE)));
          if result<0 then
            result:=0;
        end
        else
        begin
          BASS_ChannelSetPosition(chan,BASS_ChannelSeconds2Bytes(chan,arg),BASS_POS_BYTE);

          code:=MRC_STATUS;
          arg :=RD_STATUS_POSITION+(arg shl 16);
        end;
      end;
    end;
  end;

  if code=MRC_STATUS then
  begin
    if arg=RD_STATUS_GET then
      result:=PlayStatus
    else
    begin

      code:=(arg and $FFFF);
      arg :=hiword(arg);
      // this is just events
      case code of
        RD_STATUS_MUTED: begin
        end;

        RD_STATUS_RECORD: begin
        end;

        RD_STATUS_POSITION: begin
        end;

      else
        // these statuses are for events and some tasks
        artist:=nil;
        title :=nil;
        case code of
          RD_STATUS_NOSTATION: begin
            SetStatus(ActiveContact,ID_STATUS_OFFLINE);
            ActiveContact:=0;

            DBDeleteSetting(0,PluginName,optActiveURL);

            PlayStatus:=RD_STATUS_NOSTATION;
            // empty message
          end;

          RD_STATUS_STOPPED: begin
            if ActiveContact<>0 then //!! fools proof
              DBDeleteSetting(ActiveContact,strCList,optStatusMsg);

            DBDeleteSetting(0,PluginName,optTitle);
            DBDeleteSetting(0,PluginName,optArtist);

            PlayStatus:=RD_STATUS_STOPPED;
            // empty message
          end;

          RD_STATUS_ABORT: begin
            PlayStatus:=RD_STATUS_ABORT;
            // status as message
          end;

          RD_STATUS_CONNECT: begin
            SetStatus(ActiveContact,ID_STATUS_AWAY);
            PlayStatus:=RD_STATUS_CONNECT;
            // status as message
          end;

          RD_STATUS_NEWSTATION: begin
            arg:=ActiveContact;
            PlayStatus:=RD_STATUS_PLAYING;
          end;

          RD_STATUS_NEWTRACK: begin
            SetStatus(ActiveContact,ID_STATUS_ONLINE);
            DBWriteUnicode(0,PluginName,optActiveURL,ActiveURLw);

            DBWriteString(0,PluginName,optActiveCodec,GetMusicFormat);
            arg :=lparam(ActiveURLw);

            // for case when tags was in meta
            artist:=DBReadUnicode(0,PluginName,optArtist);
            title :=DBReadUnicode(0,PluginName,optTitle);
            PlayStatus:=RD_STATUS_PLAYING;
            // status as message
          end;

          RD_STATUS_NEWTAG: begin
          // must be updated tags
            artist:=DBReadUnicode(0,PluginName,optArtist);
            title :=DBReadUnicode(0,PluginName,optTitle);

            PlayStatus:=RD_STATUS_PLAYING; // maybe keep RD_STATUS_NEWTAG?
          end;

          RD_STATUS_PLAYING: begin
            SetStatus(ActiveContact,ID_STATUS_ONLINE);
            PlayStatus:=RD_STATUS_PLAYING;
            // status as message
          end;

          RD_STATUS_PAUSED: begin
            if arg=0 then
            begin
              PlayStatus:=RD_STATUS_PLAYING;
              if StrPosW(ActiveURLw,'://')=nil then //local only
              begin
                artist:=DBReadUnicode(0,PluginName,optArtist);
                title :=DBReadUnicode(0,PluginName,optTitle);
              end;
            end
            else
              PlayStatus:=RD_STATUS_PAUSED;
            // status as message
          end;
        else
          exit;
        end;
        ConstructMsg(artist,title,PlayStatus);
        mFreeMem(artist);
        mFreeMem(title);
      end;

      NotifyEventHooks(hhRadioStatus,code,arg);
    end;

  end;
end;