#include "mcdp.h"
short maxx,maxy;  /* screenmaxima */

static void draw_hline(int i, char *ch); /* draw an hline */
static void draw_box(int x1, int y1, int x2, int y2); /* draw a box */
static void draw_method(char *msg);
static void draw_initscr(void);
static void draw_tracks(struct mcdp *cd);

static void draw_hline(int i, char *ch) {
 int x;

 for (x=i; x>1; x--) {
	show1(ch);
 }

 return;
}

static void draw_box(const int x1, const int y1, const int x2, const int y2) {
 int i;
 gotoxy(x1,y1);show1(AC_TL);draw_hline(x2-x1,AC_HL);show1(AC_TR);
 for (i=1;i!=y2-1;++i) {
  gotoxy(x1,y1+i);show1(AC_VL);
  gotoxy(x2,y1+i);show1(AC_VL);
 }
 gotoxy(x1,y2);show1(AC_BL);draw_hline(x2-x1,AC_HL);show1(AC_BR);
 return;
}

static void draw_method(char *msg) {
 gotoxy(11,4);
 _printf(C_STATUS "%s" C_NORMAL, msg);
 return;
}

static void draw_initscr(void) {
 int i;

 tty_getsize(&maxx,&maxy);
 show1(C_NORMAL T_CLEAR C_BOX);
 draw_box(1,1,maxx,maxy); /* the bigbox */
 gotoxyw(1,8, AC_ML);
 if (maxx > 1) draw_hline(maxx-1,AC_HL);
 show1(AC_MR); /* border */

 if (cddb) { /* vline */
  gotoxy(maxx/2,1);show1(AC_MB);
  for (i=2;i<5;i++) {
   gotoxy(maxx/2,i);
   show1(AC_VL);
  }
  gotoxy(maxx/2,i);show1(AC_BL);
  if (maxx/2 > 1) draw_hline(maxx/2,AC_HL);
  show1(AC_MR);
 }
 show1(C_HEADLINE);
 gotoxyw(3,2, "mcdp version " MCDP_VERSION);
 if (cddb) gotoxyw(maxx/2+2,2,"freedb info");
 gotoxy(9,8); _printf(" tracklist %d ", pluskey);
 show1(C_DESCRIPT);
 gotoxyw(3,3, "Status:");
 gotoxyw(3,4, "Method:");
 gotoxyw(3,5, "Volume:");
 gotoxyw(3,6, "Track:");
 gotoxyw(18,6, "CD:");
 if (cddb) {
  gotoxyw(maxx/2+2,3,"Source:");
  gotoxyw(maxx/2+2,4,"DiscID:");
  gotoxyw(maxx/2+19,4,"Len:");
 }
 return;
}

/* this function looks strange since cddb =:) */
static void draw_tracks(struct mcdp *cd) {
 register int i,m; /* title/modifier/realtitle */
 int x=0; /* x=diffs to real */

 for (i=9;i<maxy;i++) for(x=3;x<maxx;x++) gotoxyw(x,i," ");
 if (cddb) { /* if we have cddb */
  gotoxyw(maxx/2+10,3,C_STATUS);
  if (cddb==CDDB_WORKMAN) show1("~/.workmandb");
  else if(cddb==CDDB_LOCAL) show1(getenv("CDDB_PATH"));
  else _printf("remote, via %s:%s",ip,port); /* can only be REMOTE */
  gotoxy(maxx/2+10,4);_printf("%08x",cd_discid(&cd[0]));
  gotoxy(maxx/2+24,4);_printf("%ds",cd->t[0].cddb);
/* titleinfo */
  cd->t[0].name[maxx-3]='\0';
  gotoxy(3,7); _printf(C_NORMAL T_BOLD "%s",cd->t[0].name); /* always */
  gotoxy(15,9);show1(C_BOX AC_MB);
  for(i=9;i<maxy;i++) { gotoxyw(15,i,AC_VL); }
  gotoxy(15,maxy);show1(AC_MT C_NORMAL);
 }
 for(i=offset;(i<=cd->title[1] && i<=MCDP_CDAUDIO_MAX); i++) {
/* automatic offset change - these are overriden by pressing [ or ] */
  if(updates[U_TRACKS]==1) { /* if==2, don't scroll */
   if(cd->title[0]>(i+maxy-10)) {
    offset=cd->title[0]-maxy+10;
    i=offset; continue;
   }
   if(cd->title[0]<offset) {
    offset=1;
    i=cd->title[0]; continue;
   }
  }
  if ((i-offset)==(maxy-9)) { break; }
  m=((i-(pluskey+1)*10)<0 && (i-(pluskey+1)*10)>-11); /* is shortcut? */

  gotoxy(3,9+i-offset);
  if (m&&(i==cd->title[0])) _printf(C_STATUS "%02d" C_NORMAL, i); /* current */
  else if (m||(i==cd->title[0])) _printf(T_BOLD "%02d" C_NORMAL, i); /* current */
  else _printf("%02d",i); /* nothing special */
  if (i==cd->title[0]) show1(T_BOLD); /* current */
  _printf("%c - %02d:%02d\n",
   cd->t[i].audio?'d':'a',
   cd->t[i].min,
   cd->t[i].sec);

 if (cddb) { /* if we have cddb */
  gotoxy(17,9+i-offset);
  cd->t[i].name[maxx-17]='\0';
  _printf("%s",cd->t[i].name);
 } /* cddb */
  if(i==cd->title[0]) show1(C_NORMAL); /* current */
 }

 show1(C_STATUS); /* trackmodifier */
 return;
}

void draw_status(char *msg, short again) {
 gotoxy(11,3);
 _printf(C_STATUS "%-13s" C_NORMAL, msg);
 if (again) {
  updates[U_STATUS]=1;
  sleep(again);
 }
 return;
}

void draw_updatescr(struct mcdp *cd) {
 if (cd_readsubchannel(cd)<0) {
  draw_status("no disc (e/c)",0);
  return;
 }

 show1(C_NORMAL);
 if (updates[U_ALL]) {
  signal(SIGWINCH,tty_resize);
  show1(C_NORMAL T_CLEAR);
  tty_getsize(&maxx,&maxy);
  if (maxx<50 || maxy<10) {
   _printf(T_NORMAL T_CLEAR "Sorry, you need at least a termsize of 50x10.\n");
   tty_mode(TERM_QUIT);
  }
  cddb=cd_readtracks(&cd[0]);
  draw_initscr();
  updates[U_TRACKS]=updates[U_STATUS]=updates[U_METHOD]=updates[U_VOLUME]=1;
  updates[U_ALL]=0;
 }

 if (updates[U_STATUS]) {
  draw_status(
  (cd->status==CDROM_AUDIO_NO_STATUS) ? "no status":"" &&
  (cd->status==CDROM_AUDIO_ERROR    ) ? "error    ":"" &&
  (cd->status==CDROM_AUDIO_COMPLETED) ? "completed":"" &&
  (cd->status==CDROM_AUDIO_PAUSED   ) ? "paused   ":"" &&
  (cd->status==CDROM_AUDIO_PLAY     ) ? "playing  ":"" &&
  (cd->status==CDROM_AUDIO_INVALID  ) ? "invalid  ":"",0);
  updates[U_STATUS]=0;
 }

 if (updates[U_METHOD]) {
  draw_method(
  (cd->method==M_PLAY_CD)    ? "play cd     ":"" &&
  (cd->method==M_REPEAT_CD)  ? "repeat cd   ":"" &&
  (cd->method==M_REPEAT_TRK) ? "repeat track":"" &&
  (cd->method==M_INTRO)      ? "intro       ":"");
  updates[U_METHOD]=0;
 }

 if (updates[U_TRACKS]) {
  draw_tracks(&cd[0]);
  updates[U_TRACKS]=0;
 }

 show1(C_STATUS);
 if (updates[U_VOLUME]==1) {
  gotoxy(11,5);
  _printf("%d%%  ", (int)(cd->vol.channel0/2.55));
  updates[U_VOLUME]=0;
 }

 /* always */
 gotoxy(11,6);
 _printf("%02d:%02d",
  cd->cds.cdsc_reladdr.msf.minute,
  cd->cds.cdsc_reladdr.msf.second);
 gotoxy(23,6);
 _printf("%02d:%02d",
  cd->cds.cdsc_absaddr.msf.minute,
  cd->cds.cdsc_absaddr.msf.second);
  show1(T_HOME);
 return;
}
