#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include "lyrics.h"
#include "config.h"

#define CODECONV(x) x
#ifdef I18N
#       include <locale.h>
#       ifdef   JAPANESE
#       include "kanji_code.h"
#       undef CODECONV
#       define CODECONV(x) sj_to_euc(x)
#       endif
#endif

#ifdef DEBUG 
#define DPRINT(x) printf(x)
#else
#define DPRINT(x)
#endif

#define LIST_NUM 6

#define LYRICS_PATH_ENV "LYRICS_PATH"

LYRICS *lyrics;
LYRICS *lyrics_current;
int l_count;
GtkWidget *l_win;
GtkWidget *list;
long lyrics_status;

/* Scrolled Window Vadjustment */
GtkAdjustment *va;

/* get basename from filename */

gchar *basename2(gchar * path);
/*
{
 	gint i;

	DPRINT("basename2(): ");

	for (i = strlen(path) - 1; i > 0; i--) {
		DPRINT("-");
		if (path[i] == '/') {
			i++;
			DPRINT(" done.\n");
			return (gchar *) (path + i);
		}
	}
	DPRINT(" done.\n");
	return path;
}
*/

int fscanline ( FILE *fp )
{
  int lines=0;
  fseek(fp,0,SEEK_SET);

  while ( !feof(fp) ){
    if ( (char)fgetc(fp)=='\n' ) lines++;
  }
  return ( lines );
}

int fgetline(char *BUFF, FILE *fp, int line)
{
  int count=0;
  int r_count=0;
  int i;
  char dat;

  fseek(fp,0,SEEK_SET);
  while ( !feof(fp) ){
    if ( count==line ) {
      while(r_count<255){
	dat=(char)fgetc(fp);
	if ( dat != '\r' && dat != '\n' ) {*(BUFF+r_count)=dat; r_count++;}
	else break;
      }
      *(BUFF+r_count)='\0';
      return ( 0 );
    }
    if ( fgetc(fp)=='\n' ) {
      count++;
    }
  }
  return ( -1 );
}

int mp3_to_txt ( char *BUFF, char *filename )
{
  int i;
  int j = strlen(filename);
  strcpy(BUFF, filename);
  strcpy(BUFF+j-3, "txt" );
  DPRINT("Lyrios Filename:");
  DPRINT(BUFF);
  DPRINT("\n");
  return ( 0 );
}

LYRICS *ly_getwrdtxt(char *filename)
{
  FILE *fp=NULL;
  char BUFF[255];
  char BUFF2[255];
  char *lyrics_path;
  LYRICS *l_tmp=NULL;
  LYRICS *l_tmp2=NULL;
  LYRICS *ltop=NULL;
  LYRICS *llast=NULL;
  int lines;
  int i;
  int sec,min;

  DPRINT ( "ly_getwrdtxt()\n" );
  
  lyrics_path=(char *)getenv(LYRICS_PATH_ENV);
  if ( lyrics_path!=NULL ){
  mp3_to_txt(BUFF2,basename2(filename));
  sprintf(BUFF, "%s/%s", lyrics_path, BUFF2);
  fp=fopen(BUFF,"r");
  }
  if ( fp == NULL ) {
    mp3_to_txt(BUFF, filename);
    fp=fopen(BUFF,"r");
    if ( fp == NULL ) {DPRINT("Can't open txt"); return ( NULL );}
  }

  lines=fscanline(fp);

  for ( i = 0; i < lines; i++) {
    if ( fgetline(BUFF,fp,i) < 0 ) {
       clr_lyrics(ltop);
       return(NULL);
    }

    if (ltop==NULL) {
      llast=l_tmp=ltop=(LYRICS*)malloc(sizeof(LYRICS));
      l_tmp->time=0;
      l_tmp->prev=NULL;
    }
    else {
      l_tmp->next=(LYRICS*)malloc(sizeof(LYRICS));
      l_tmp2=l_tmp;
      llast=l_tmp=l_tmp->next;
      l_tmp->prev=l_tmp2;
    }

    if ( BUFF[0]!='[' ) {
      l_tmp->time=-1;
      strcpy ( l_tmp->word, BUFF );
    }
    else
      {
	sscanf(BUFF,"[%d:%d]", &(min), &(sec) );
	l_tmp->time=min*60+sec;
	strcpy (l_tmp->word, &BUFF[7] );
      }
    l_tmp->next=NULL;
  }
  fclose (fp);

  l_tmp=llast;
  if ( llast->time==-1 )
    llast->time=65535;
  while ( l_tmp!=NULL ) {
    if ( l_tmp->time==-1 )
      l_tmp->time=l_tmp->next->time;
    l_tmp=l_tmp->prev;
  }
  
  l_tmp=ltop;
  while(l_tmp!=NULL){
    #ifdef DEBUG
    printf ( "[%d]%s\n", l_tmp->time, CODECONV(l_tmp->word));
    #endif
    l_tmp=l_tmp->next;
  }

  return ( ltop );
}

void clr_lyrics ( LYRICS *lyrics )
{
  LYRICS *tmp;
  while ( lyrics != NULL ) {
    tmp=lyrics->next;
    free(lyrics);
    lyrics=tmp;
  }
}

gint l_close (GtkWidget *widget, gpointer *gptr )
{
  gtk_widget_hide ( l_win );
}

GtkWidget *init_l_win(void)
{
  GtkWidget *box1, *box2;
  GtkWidget *button;
  GtkWidget *table;
  GtkWidget *scrolled_win;
  char BUFF[255];
  int i;
  l_count=0;

  DPRINT ( "init_l_win();\n" );
  l_win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_name( l_win, "l_win" );
  gtk_widget_set_usize (l_win, 400, 300);

  gtk_signal_connect (GTK_OBJECT (l_win), "destroy",
                      GTK_SIGNAL_FUNC (l_close), NULL);
  gtk_signal_connect_object (GTK_OBJECT (l_win), "delete_event",
                             GTK_SIGNAL_FUNC (l_close),
                             GTK_OBJECT (l_win));
  
  gtk_container_border_width (GTK_CONTAINER (l_win), 0);
    
  box1 = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (l_win), box1);
  gtk_widget_show (box1);

  box2 = gtk_vbox_new (FALSE, 10);
  gtk_container_border_width (GTK_CONTAINER (box2), 10);
  gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
  gtk_widget_show (box2);

  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, 
				  GTK_POLICY_AUTOMATIC);
  gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
  va =  gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_win));
  gtk_widget_show (scrolled_win);

  list = gtk_list_new ();
  gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
  gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
#ifdef GLIB_MINOR_VERSION
    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
#else
    gtk_container_add (GTK_CONTAINER (scrolled_win), list);
#endif

  gtk_container_set_focus_vadjustment (GTK_CONTAINER (list), va);

  gtk_widget_show (list);

  button = gtk_button_new_with_label ("Close");
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
		      GTK_SIGNAL_FUNC(l_close),
		      NULL );
  gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
  gtk_widget_show (button);

  gtk_list_select_item(GTK_LIST(list),0 );
  return ( l_win );
}

void open_lyrics ( GtkWidget *l_win, char *filename, gchar show_flag )
{
  GtkWidget *list_item;
  LYRICS *l_tmp;
  char BUFF[255];

  DPRINT("open lyrics file and setting()\n");

  lyrics_status=0;
  clr_lyrics(lyrics);
  l_tmp=lyrics=ly_getwrdtxt(filename);
  if ( lyrics != NULL ){
    sprintf (BUFF, "Lyrics - %s -", CODECONV(lyrics->word) );
    gtk_window_set_title(GTK_WINDOW(l_win), BUFF);
  }
  else
  {
    sprintf (BUFF, "Lyrics - %s -", "No Lyrics File" );
    gtk_window_set_title(GTK_WINDOW(l_win), BUFF);
  }

  if (l_count!=0);{
    gtk_list_clear_items(GTK_LIST(list),0,l_count);
    l_count=0;
  }

  while (l_tmp!=NULL) {
    list_item = gtk_list_item_new_with_label (CODECONV(l_tmp->word));
    gtk_container_add (GTK_CONTAINER (list), list_item);
    gtk_widget_show (list_item);
    l_count++;
    l_tmp=l_tmp->next;
  }

  if ( show_flag != 1 )return; 
  if ( lyrics!=NULL ) {
    gtk_list_select_item(GTK_LIST(list),0 );
    gtk_widget_show(l_win); 
    gtk_adjustment_set_value(va,va->lower);
    }
  else
    gtk_widget_hide(l_win); 

}

void update_lyrics ( long time )
{
  LYRICS *lyrics_tmp;
  float current_view;
  
  DPRINT("update lyrics status()\n");

  lyrics_status=0;

  lyrics_tmp=lyrics;
  if ( lyrics_tmp==NULL || l_count==0 ) return;

  DPRINT("\ttime seek\n");
  while ( lyrics_tmp->time <= time ) {
    lyrics_status++;
    lyrics_tmp=lyrics_tmp->next;
    if ( lyrics_tmp==NULL ) break;
  }  
  if ( lyrics_status==0 ) return;

  if ( lyrics_tmp == lyrics_current ) return;

  DPRINT("\tselect item\n");
  lyrics_current=lyrics_tmp;
  gtk_list_select_item(GTK_LIST(list),lyrics_status-1);
    
  /* Auto Scroll  */
  DPRINT("\tmove view adgustment\n");
  current_view=va->upper*((float)(lyrics_status)/(float)l_count);
  if ( current_view < va->page_size/2.0 )
    gtk_adjustment_set_value(va, va->lower);
  else if ( current_view > (va->upper - va->page_size/2.0) )
    gtk_adjustment_set_value(va, va->upper-(va->page_size));
  else
    gtk_adjustment_set_value(va, current_view-(va->page_size/2.0));

#ifdef DEBUG
    printf ("va=%f ls=%d lc=%d\n",va->value,lyrics_status,l_count);
    printf ("ps=%f upper=%f lower=%f\n",va->page_size,va->upper,va->lower);
#endif

}
