/*
 *  Copyright (c) by Jaroslav Kysela (Perex soft)
 */

#include <fcntl.h>
#include <unistd.h> 
#include <string.h>
#include <malloc.h>
#include "pmod.h"

struct sPlayList *playListFirst = NULL;
struct sPlayList *playListLast = NULL;
struct sPlayList *playListCurrent = NULL;

struct sPlayList *playListAdd( char *songFilename )
{
  struct sPlayList *pl;
  int handle;

  if ( songFilename == NULL || songFilename[ 0 ] == 0 )
    return NULL;
  if ( ( handle = open( songFilename, O_RDONLY ) ) < 0 )
    {
      dprintf( "I cann't open file '%s'. Skipping..\n", songFilename );
      return NULL;
    }
  close( handle );
  if ( ( pl = (struct sPlayList *)malloc( sizeof( struct sPlayList ) ) ) == NULL )
    fatal( "playListAdd: not enough memory (struct)" );
  memset( pl, 0, sizeof( struct sPlayList ) );
  if ( ( pl -> filename = (char *)malloc( strlen( songFilename ) + 1 ) ) == NULL )
    fatal( "playListAdd: not enough memory (filename)" );
  strcpy( pl -> filename, songFilename );
  pl -> next = NULL;
  if ( !playListFirst )
    {
      pl -> prev = NULL;
      playListFirst = playListLast = pl;
    }
   else
    {
      playListLast -> next = pl;
      pl -> prev = playListLast;
      playListLast = pl;
    }
  return pl;
}

void playListFree()
{
  struct sPlayList *pl;

  while ( playListFirst )
    {
      pl = playListFirst;
      playListFirst = playListFirst -> next;
      free( pl -> filename );
      free( pl );
    }  
  playListFirst = playListLast = playListCurrent = NULL;
}

int rangeCheck( char *range )
{
  int min, max, cmpMax = -1;
  char str[ MAX_RANGE_SIZE + 1 ];

  if ( !range || *range == 0 ) return 0;	/* NULL is for me ok */
  while ( *range )
    {
      if ( *range < '0' && *range > '9' ) return 1;
      sscanf( range, "%i", &min );
      if ( cmpMax > min ) return 1;
      cmpMax = min;
      sprintf( str, "%i", min );
      if ( strlen( range ) < strlen( str ) ) return 1;
      range += strlen( str );
      if ( !*range ) continue;
      if ( *range == ',' ) { range++; continue; }
      if ( *range != '-' ) return 1;
      range++;
      if ( *range < '0' && *range > '9' ) return 1;
      sscanf( range, "%i", &max );
      if ( cmpMax > max ) return 1;
      cmpMax = max;
      sprintf( str, "%i", max );
      if ( strlen( range ) < strlen( str ) ) return 1;
      range += strlen( str );
      if ( min > max ) return 1;
      if ( !*range ) continue;
      if ( *range != ',' ) return 1;
      range++;
    }
  return 0;
}

int rangeFirst( char *range, int min )
{
  int tmp;

  if ( !range || *range == 0 ) return min;
  sscanf( range, "%i", &tmp );
  return tmp < min ? min : tmp;
}

int rangeLast( char *range, int max )
{
  int tmp;
  char *first = range;
  
  if ( !range || *range == 0 ) return max;
  range += strlen( range ) - 1;
  while ( range != first && *range != ',' && *range != '-' ) range--;
  if ( *range == ',' || *range == '-' ) range++;
  sscanf( range, "%i", &tmp );
  return tmp > max ? max : tmp; 
}

int rangeNext( char *range, int prev, int max )
{
  int min1, max1, oldPrev;
  char str[ MAX_RANGE_SIZE + 1 ];

  if ( !range || *range == 0 ) return ++prev > max ? -1 : prev;
  oldPrev = prev;
  while ( *range )
    {
      sscanf( range, "%i", &min1 );
      sprintf( str, "%i", min1 );
      range += strlen( str );
      if ( min1 > prev ) 
        {
          prev = min1;
          break;
        }
      if ( !*range ) continue;
      if ( *range == ',' ) { range++; continue; }
      range++;
      sscanf( range, "%i", &max1 );
      sprintf( str, "%i", max1 );
      range += strlen( str );
      if ( prev < max1 )
        {
          prev++;
          break;
        }
      if ( *range ) range++;
    }
  if ( oldPrev == prev ) return -1;
  return prev > max ? -1 : prev;
}

int rangePrev( char *range, int next, int min )
{
  int min1, max1, oldNext, parse;
  char *first = range;

  if ( !range || *range == 0 ) return --next < min ? -1 : next;
  oldNext = next;
  range += strlen( range ) - 1;
  parse = 1;
  while ( range != first || parse )
    {
      parse = 0;
      while ( range != first && *range != ',' && *range != '-' ) range--;
      sscanf( range != first ? range + 1 : range, "%i", &max1 );
      if ( max1 < next )
        {
          next = max1;
          break;
        }
      if ( range == first ) continue;
      if ( *range == ',' ) { range--; continue; }
      range--;
      while ( range != first && *range != ',' && *range != '-' ) range--;
      sscanf( range != first ? range + 1 : range, "%i", &min1 );
      if ( next > min1 )
        {
          next--;
          break;
        }
      if ( range != first ) range--;
      parse = 1;
    }
  if ( oldNext == next ) return -1;
  return next < min ? -1 : next;
}

int rangeIn( char *range, int value )
{
  int min1, max1;
  char str[ MAX_RANGE_SIZE + 1 ];

  if ( !range || *range == 0 ) return 0;
  while ( *range )
    {
      sscanf( range, "%i", &min1 );
      sprintf( str, "%i", min1 );
      range += strlen( str );
      if ( min1 == value ) return 1;
      if ( !*range ) continue;
      if ( *range == ',' ) { range++; continue; }
      range++;
      sscanf( range, "%i", &max1 );
      sprintf( str, "%i", max1 );
      range += strlen( str );
      if ( min1 <= value && max1 >= value ) return 1;
      if ( *range ) range++;
    }
  return 0;
}
