unit searchtrack;

interface
uses forms,controls,stdctrls,transparentpanel,classes,ExtCtrls,graphics,bitmapactionbutton,scrolllistbox,windows,main,sysutils,isconnected;



type tsearchthread = class (TThread)
 private
 alb : integer;
 tracktitle : string;
 track : integer;
 parentcanvas : tcanvas;
 procedure additem;
 procedure updatestatus;
 function findkeyword(s,sub : string) : boolean;
  protected
   procedure Execute; override;
  public
   cancel : boolean;
   keyword : string;
   listbox : tscrolllistbox;
   progresscanv : tcanvas;
   icon : string;
  end;



type
  ttracksearch = class(TTransparentPanel)
   keywords : tedit;
    action_but : timage;
    action_label : tlabel;
    keyboard_label : tlabel;
    keyboard_but : timage;
    lbshape : tshape;
    lbshape2 : tshape;
    st : tsearchthread;

   procedure action_butMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
   procedure action_butMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  procedure keyboard_butMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
   procedure keyboard_butMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);

   procedure action_butClick(sender : TObject);
   procedure keyboard_butClick(sender : TObject);
   procedure lbClick(sender : TObject);
   procedure keywordEnter(sender : TObject);
   procedure keywordExit(sender : TObject);
   procedure keywordsOnKeyDown(Sender : TObject;var Key: Word; Shift: TShiftState);
  public
   lb : tscrolllistbox;

   constructor  Create(AOwner : TComponent);override;
  procedure Resize;  override;
  procedure lostfocus(sender : TObject);
  end;

implementation
uses global,jukeboxform;



constructor ttracksearch.Create(AOwner : TComponent);
begin
inherited create(Aowner);
keywords:=tedit.Create(self);
keywords.parent:=self;
action_but := timage.Create(self);
action_but.Parent:=self;
action_label := Tlabel.Create(self);
action_label.Parent:=self;
lb := Tscrolllistbox.create(self);
lb.parent:=self;
lbshape2 := Tshape.create(self);
lbshape2.parent:=self;
lbshape := Tshape.create(self);
lbshape.parent:=self;
keyboard_but := timage.Create(self);
keyboard_but.Parent:=self;
keyboard_label := Tlabel.Create(self);
keyboard_label.Parent:=self;
end;

procedure ttracksearch.resize;
begin
 inherited resize;
 with keywords do begin
    Font.name:=JUKEBOXFONT;
    Font.size:=aspy(20);
    Width:=parent.width div 2;
    Left:=(parent.Width div 2)-(keywords.width div 2);
    Top:=parent.Height div 20;
    Visible:=true;
    BringToFront;
    color:=clblack;
    font.color:=clgray;
    OnEnter:=keywordenter;
    OnExit:=keywordexit;
    OnClick:=keywordenter;
    OnKeydown:=keywordsOnKeyDown;
 end;
 with action_but do begin
    top:=keywords.top+keywords.height+aspy(10);
    width:=aspx(100);
    height:=aspy(30);
    picture.Bitmap.LoadFromResourceName(hinstance,'WIDEBUTUP');
    stretch:=true;
    left:=(parent.Width div 2) - (width div 2);
    setupnumlabel(action_label,action_but,'Search');
 end;

  with keyboard_but do begin
    top:=0;
    width:=aspx(100);
    height:=aspy(30);
    picture.Bitmap.LoadFromResourceName(hinstance,'KEYBOARDICONUP');
    transparent:=true;
    stretch:=true;
    left:=0;
    setupnumlabel(keyboard_label,keyboard_but,'');
 end;

    action_label.onmousedown:=action_butMouseDown;
    action_label.onmouseup:=action_butMouseUp;
    action_label.onclick:=action_butClick;

    keyboard_label.onmousedown:=keyboard_butMouseDown;
    keyboard_label.onmouseup:=keyboard_butMouseUp;
    keyboard_label.onclick:=keyboard_butClick;



  with lb do begin
    linespacing:=2;
    left:=aspy(4);
    width:=(parent.Width-(parent.Parent.left*2));
    top:=action_but.Top+action_but.Height+aspy(10);
    height:=(parent.Height-top)-aspy(4);;
    color:=clblack;
    font.name:=JUKEBOXFONT;
    font.size:=aspy(8);
    showlabels:=false;
    drawmode:=true;
    font.color:=clgray;
    onclick:=lbClick;
    resize;
  end;

  lbshape2.Pen.color:={viewgit}{/viewgit}2087A1;
  lbshape2.BoundsRect:=lb.BoundsRect;
  lbshape2.Left:=lb.Left-aspx(2);
  lbshape2.Top:=lb.top-aspy(2);
  lbshape2.Width:=lb.width+aspx(4);
  lbshape2.height:=lb.height+aspy(4);
  lbshape2.Pen.width:=aspy(4);
  lbshape2.brush.style:=bsclear;

  lbshape.BoundsRect:=lb.BoundsRect;
  lbshape.Left:=lbshape.Left-aspx(4);
  lbshape.Top:=lbshape.top-aspy(4);
  lbshape.Width:=lbshape.width+aspx(8);
  lbshape.height:=lbshape.height+aspy(8);
  lbshape.Pen.width:=aspy(2);
  lbshape.Pen.color:=FONTCOL;
  lbshape.brush.style:=bsclear;
  lbshape.BringToFront;
end;

procedure TTracksearch.action_butMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
begin
    action_but.picture.Bitmap.LoadFromResourceName(hinstance,'WIDEBUTDOWN');

end;

procedure TTracksearch.action_butMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
begin
    action_but.picture.Bitmap.LoadFromResourceName(hinstance,'WIDEBUTUP');

end;

procedure TTracksearch.keyboard_butMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
begin

end;

procedure TTracksearch.keyboard_butMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
begin

end;


procedure TTrackSearch.action_butClick(sender : TObject);
begin
//if jukebox.keyboardpanelpanel.Tag=1 then jukebox.keyboardpanelclick(nil);

if keyboardshowing=true then begin
keyboard_butClick(nil);
end;

lb.clear;
if st<>nil then begin
  if st.Terminated=false then begin
    st.cancel:=true;
    st.WaitFor;
    st.free;
  end;
end;
jukebox.domessage('Searching...');
st:=tsearchthread.Create(true);
st.parentcanvas:=self.Canvas;
st.listbox:=lb;

st.keyword:=keywords.text;
st.Resume;
end;

procedure tsearchthread.additem;
var
o : tobject;
i : integer;
already : boolean;
begin
if jukebox.thumbpanel.visible=false  then o:=nil else o:=jukebox.thumbs.pl.items[alb-1].picture;
  if tracktitle<>'' then tracktitle:=tracktitle+' -';
  already:=false;

  for i:=0 to listbox.items.Count-1 do begin
   if (TScrollListItemAdditonalInfo(listbox.items.Objects[i]).AlbumNumber=alb) then if (TScrollListItemAdditonalInfo(listbox.items.Objects[i]).TrackNumber=track) then already:=true;
  end;



  if already=false then begin
  listbox.additemandinfo(tracktitle+album[alb].artist+', '+album[alb].album,alb,track,o,icon,'');
  end;

end;

procedure tsearchthread.updatestatus;
begin
  if listbox.items.count=1  then jukebox.domessage('Search completed. Found 1 item') else jukebox.domessage('Search completed. Found '+inttostr(listbox.items.count)+' items');

end;

function tsearchthread.findkeyword(s,sub : string) : boolean;
begin
result:=false;
s:=uppercase(s);
sub:=uppercase(sub);
if pos(sub,s)<>0 then result:=true;

end;

type tknownalbums=record
path : string;
number : integer;
end;

procedure tsearchthread.Execute;
var
n,t : integer;
s : string;
al : array of string;
fl : textfile;
knownalbums : array of tknownalbums;
knownalbumscount : integer;
begin
knownalbumscount:=0;
tracktitle:='';
track:=-1;
setlength(al,albumcount+1);
  icon:='CDICON';
for n:=1 to albumcount do begin
  s:=album[n].artist+' '+album[n].album;
  alb:=n;
  al[n]:=config.path+'\'+album[n].path+'\title.dat';

  if findkeyword(s,keyword)=true then begin
    inc(knownalbumscount);
    setlength(knownalbums,knownalbumscount);
    knownalbums[knownalbumscount-1].path:=al[n];
    knownalbums[knownalbumscount-1].number:=n;
    synchronize(additem);
  end;
  if cancel=true then begin
     setlength(al,0);
     terminate;
     exit;
  end;

  end;

icon:='NOTES';
for n:=1 to albumcount do begin
  if fileexists(al[n]) then begin
    assignfile(fl,al[n]);
    s:='';
    try
     reset(fl);
     t:=0;
     while(not eof(fl)) do begin
       inc(t);
       readln(fl,s);
       alb:=n;
       tracktitle:=s;
       track:=t;
       if s<>'' then if findkeyword(s,keyword)=true then synchronize(additem);
         if cancel=true then begin
              closefile(fl);
              setlength(al,0);
              terminate;
              exit;
         end;
     end;
    except;
     closefile(fl);
    end;
      if cancel=true then begin
        setlength(al,0);
        terminate;
         exit;
      end;
  end;
end;

//Add tracks of albums already found by album title

for n:=1 to knownalbumscount do begin
  if fileexists(knownalbums[n-1].path) then begin
    assignfile(fl,knownalbums[n-1].path);
    s:='';
    try
     reset(fl);
     t:=0;
     while(not eof(fl)) do begin
       inc(t);
       readln(fl,s);
       alb:=knownalbums[n-1].number;
       tracktitle:=s;
       track:=t;
       if s<>'' then synchronize(additem);
         if cancel=true then begin
              closefile(fl);
              setlength(al,0);
              terminate;
              exit;
         end;
     end;
    except;
     closefile(fl);
    end;
      if cancel=true then begin
        setlength(al,0);
        terminate;
         exit;
      end;
  end;
end;


setlength(al,0);
setlength(knownalbums,0);
synchronize(updatestatus);

end;

procedure Ttracksearch.lbClick(sender: TObject);
begin
if lb.itemindex<0 then exit;
if lb.itemindex>lb.items.count then exit;
if lb.items.objects[lb.itemindex]<>nil then begin
jukebox.searchpanellbclick(TScrollListItemAdditonalInfo(lb.items.objects[lb.itemindex]).AlbumNumber,TScrollListItemAdditonalInfo(lb.items.objects[lb.itemindex]).TrackNumber);
end;

end;

procedure TTrackSearch.keywordEnter(sender : TObject);
begin
//  if jukebox.keyboardpanelpanel.Tag=0 then jukebox.keyboardpanelClick(nil);
if keyboardshowing=false then osk(true,false);
keyboard_but.tag:=0;
keyboard_but.picture.Bitmap.LoadFromResourceName(hinstance,'KEYBOARDICONUP');
end;


procedure TTrackSearch.keywordExit(sender : TObject);
begin
osk(false,false);
keyboard_but.tag:=1;
keyboard_but.picture.Bitmap.LoadFromResourceName(hinstance,'KEYBOARDICONDOWN');
end;


procedure TTrackSearch.keywordsOnKeyDown(Sender : Tobject;var Key: Word; Shift: TShiftState);
begin
if key=13 then action_butClick(self);


end;


procedure TTrackSearch.keyboard_butClick(sender : TObject);
begin
if keyboard_but.tag=0 then begin
keyboard_but.tag:=1;
keyboard_but.picture.Bitmap.LoadFromResourceName(hinstance,'KEYBOARDICONDOWN');
osk(false,false);
end
else begin
keyboard_but.tag:=0;
keyboard_but.picture.Bitmap.LoadFromResourceName(hinstance,'KEYBOARDICONUP');
osk(true,false);
end;
end;


procedure TTrackSearch.lostfocus(sender: TObject);
begin
  beep;
end;

end.