//**************************************************************************
//*                     This file is part of the                           *
//*                      Mpxplay - audio player.                           *
//*                  The source code of Mpxplay is                         *
//*        (C) copyright 1998-2006 by PDSoft (Attila Padar)                *
//*                    http://mpxplay.cjb.net                              *
//*                  email: mpxplay@freemail.hu                            *
//**************************************************************************
//*  This program is distributed in the hope that it will be useful,       *
//*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *
//*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *
//*  Please contact with the author (with me) if you want to use           *
//*  or modify this source.                                                *
//**************************************************************************
//function:sublist handling

#include <string.h>
#include "playlist.h"
#include "newfunc\newfunc.h"
#include "control\control.h"

extern unsigned int playlistload;

unsigned int playlist_loadsub_check_extension(char *filename)
{
 if(playlist_loadlist_check_extension(filename)) // m3u,mxu,pls,fpl,cue
  return 1;
 if(pds_strchr(filename,'*') || pds_strchr(filename,'?')) // dir-scan
  return 1;
 return 0;
}

void playlist_loadsub_setnewinputfile(struct playlist_side_info *psi,char *newinputfile)
{
 if(newinputfile)
  if(playlistload&PLL_DRIVESCAN)
   pds_strcpy(psi->sublistnames[0],newinputfile);
  else
   pds_fullpath(psi->sublistnames[0],newinputfile);
 else
  psi->sublistnames[0][0]=0;
}

char *playlist_loadsub_getinputfile(struct playlist_side_info *psi)
{
 if(psi->sublistnames[0][0])
  return psi->sublistnames[0];
 return freeopts[OPT_INPUTFILE];
}

static void loadsub_addsubdots(struct playlist_side_info *psi)
{
 if(psi->sublistlevel){
  struct playlist_entry_info *pei=psi->firstentry;
  pei->filename=psi->filenameslastp;
  psi->filenameslastp+=pds_strcpy(psi->filenameslastp,"..")+1;
  pei->entrytype=DFT_UPLIST;
  pei->id3info[I3I_DFT_STORE]="[up-list]";
  psi->lastentry=pei;
  pei++;
  psi->firstsong=pei;
  playlist_editorhighline_set(psi,psi->firstentry);
 }
}

unsigned int playlist_loadsub_buildlist(struct playlist_side_info *psi,unsigned int loadtype,char *dslp)
{
 if((psi->editsidetype&PLT_DIRECTORY) && !psi->sublistlevel){
  playlist_loaddir_buildbrowser(psi);
  return 1;
 }
 playlist_clear_side(psi);
 loadsub_addsubdots(psi);
 return playlist_buildlist_one(psi,psi->sublistnames[psi->sublistlevel],loadtype,dslp);
}

static unsigned int load_uplist(struct playlist_side_info *psi)
{
 if(psi->sublistlevel){
  psi->sublistlevel--;
  if(!psi->sublistlevel)
   funcbit_disable(playlistload,PLL_SUBLISTS);
  if(playlist_loadsub_buildlist(psi,0,NULL)){
   playlist_search_lastdir(psi,psi->sublistnames[psi->sublistlevel+1]);
   return 1;
  }
 }
 return 0;
}

static unsigned int load_sublist(struct playlist_side_info *psi,char *listname)
{
 if(psi->sublistlevel<MAX_SUBLIST_LEVELS){
  psi->sublistlevel++;
  funcbit_enable(playlistload,PLL_SUBLISTS);
  pds_fullpath(psi->sublistnames[psi->sublistlevel],listname);
  if(playlist_loadsub_buildlist(psi,0,NULL)){
   playlist_editorhighline_set(psi,psi->firstentry);
   return 1;
  }
 }
 return 0;
}

static void load_rootlist(struct playlist_side_info *psi)
{
 if(psi->sublistlevel){
  psi->sublistlevel=0;
  funcbit_disable(playlistload,PLL_SUBLISTS);
  if(playlist_loadsub_buildlist(psi,0,NULL))
   playlist_editorhighline_set(psi,psi->firstentry);
 }
}

static unsigned int load_newlist(struct playlist_side_info *psi,char *listname)
{
 playlist_loadsub_sublist_clear(psi);
 playlist_clear_freeopts();
 funcbit_disable(playlistload,PLL_FASTLIST|PLL_STDIN |PLL_DRIVESCAN);
 playlist_loadsub_setnewinputfile(psi,listname);
 if(playlist_loadsub_buildlist(psi,0,NULL)){
  playlist_editorhighline_set(psi,psi->firstentry);
  return 1;
 }
 return 0;
}

struct playlist_side_info *playlist_loadsub_sublist_change(struct playlist_side_info *psi,unsigned long head)
{
 struct playlist_entry_info *pei=psi->editorhighline;
 unsigned int sideused;
 char filename[MAX_PATHNAMELEN];

 pds_strcpy(filename,pei->filename);
 if(head&DFTM_ROOT){
  load_rootlist(psi);
 }else{
  if(head&DFTM_UPLIST){
   load_uplist(psi);
  }else{
   if(head&DFTM_SUBLIST){
    load_sublist(psi,filename);
   }else{
    psi=psi->mvp->psil;
    sideused=psi->editsidetype&PLT_ENABLED;
    if(load_newlist(psi,filename))
     if(!sideused)
      start_sideplay(psi->mvp,psi);
   }
  }
 }
 return psi;
}

//ctrl-gray-'/' and '*'
void playlist_loadsub_search_paralell_list(struct playlist_side_info *psi,int step)
{
 unsigned int found;
 struct playlist_entry_info *pei;
 char oldsublist[MAX_PATHNAMELEN],newsublist[MAX_PATHNAMELEN];

 pds_strcpy(oldsublist,psi->sublistnames[psi->sublistlevel]);  // save original sub-playlist
 if(load_uplist(psi)){
  found=0;
  pei=psi->editorhighline;
  pei+=step;
  while((step==1 && pei<=psi->lastentry) || (step==-1 && pei>=psi->firstentry)){
   if(playlist_loadsub_check_extension(pei->filename)){
    pds_strcpy(newsublist,pei->filename);
    load_sublist(psi,newsublist);
    found=1;
    break;
   }
   pei+=step;
  }
  if(!found)
   load_sublist(psi,oldsublist); // restore original sub-playlist
  playlist_chkfile_start_norm(psi,0);
 }
}

#define SUBLIST_SEPARATOR_IN_MPXPLAYINI '|'

//slice sublist-names from one string (at loading of startup)
unsigned int playlist_loadsub_sublist_setlevels(struct playlist_side_info *psi,char *sublists)
{
 if(!sublists || !(*sublists))
  return 0;
 psi->sublistlevel=0; // it's 0 here
 do{
  char *next=pds_strchr(sublists,SUBLIST_SEPARATOR_IN_MPXPLAYINI);
  if(next)
   *next++=0;
  pds_strcpy(psi->sublistnames[psi->sublistlevel],sublists);
  if(!next)
   break;
  sublists=next;
  psi->sublistlevel++;
 }while(psi->sublistlevel<=MAX_SUBLIST_LEVELS);
 if(psi->sublistlevel)
  funcbit_enable(playlistload,PLL_SUBLISTS);
 return psi->sublistlevel;
}

//collect sublists in one string (at saving of startup)
unsigned int playlist_loadsub_sublist_getlevels(struct playlist_side_info *psi,char *destbuf,unsigned int buflen)
{
 unsigned int i=0;
 do{
  unsigned int len=pds_strlen(psi->sublistnames[i]);
  if(buflen<=len)
   break;
  pds_strcpy(destbuf,psi->sublistnames[i]);
  destbuf+=len;
  buflen-=len;
  if(i>=psi->sublistlevel)
   break;
  *destbuf++=SUBLIST_SEPARATOR_IN_MPXPLAYINI;
  buflen--;
  i++;
 }while(1);
 *destbuf++=0;
 return (min(i,psi->sublistlevel));
}

void playlist_loadsub_sublist_clear(struct playlist_side_info *psi)
{
 psi->sublistlevel=0;
 playlist_loadsub_setnewinputfile(psi,freeopts[OPT_INPUTFILE]);
 funcbit_disable(playlistload,PLL_SUBLISTS);
}
