/*				**** TITLE ****
 *
 * This file contains routines that will make a list of
 * unique movie titles this month.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "prodlist.h"

#include "scantv.h"

static ProdAPtrList *movies=NULL;
static ProdAPtrList *bydate=NULL; /* sorted by date */

int on_chan(struct Movie *mov, char *chan);
void print_shows(struct Movie *mov, char *chan, FILE *fp);
void write_letter_page(char letter);
void build_datekey(char *title, char *date, char *buf);
void store_by_date(struct Movie *mov, ProdAPtrList *bydate);
void list_by_date(FILE *fp, ProdAPtrList *bydate);
char *fixhtml(char *txt);

void init_movie_titles(void)
{
	movies = create_aptr_prodlist(5000);
}

void add_movie_title(char *flds[], int nflds)
{
	char buf[BUFSIZ], *p;
	struct Movie *movie, *m;
	struct Show *show, *sh;
	int loc;

	movie = (struct Movie *)malloc(sizeof(*movie)); /* movie structure */
	show = (struct Show *)malloc(sizeof(*show));		/* movie showing */
	if (movie==NULL || show==NULL)
	{
		fprintf(stderr, "Can't allocate memory in add_movie_title\n");
		exit(9);
	}
	show->next = NULL;	/* nothing follows yet */

	movie->title = strdup(flds[TV_TITLE]);
	movie->year = strdup(flds[TV_YEAR]);
	movie->desc = strdup(flds[TV_DESC]);
	movie->stars = strdup(flds[TV_STARS]);
	if (movie->stars==NULL) movie->stars=strdup("");
	movie->show = show;
	show->channel = strdup(flds[TV_CHAN]);
	show->date = strdup(flds[TV_DATE]);
	show->btime = strdup(flds[TV_TIME]);
	show->len = strdup(flds[TV_LEN]);

	/* build list of actors */
	*buf = '\0';
	if (nflds>TV_ACTOR1 && flds[TV_ACTOR1]!=NULL)
	{
		strcpy(buf, flds[TV_ACTOR1]);
	}
	if (nflds>TV_ACTOR2 && flds[TV_ACTOR2]!=NULL&&strlen(flds[TV_ACTOR2])>0)
	{
		strcat(buf, ", ");
		strcat(buf, flds[TV_ACTOR2]);
	}
	if (nflds>TV_ACTOR3 && flds[TV_ACTOR3]!=NULL&&strlen(flds[TV_ACTOR3])>0)
	{
		strcat(buf, ", ");
		strcat(buf, flds[TV_ACTOR3]);
	}
	if (nflds>TV_ACTOR4 && flds[TV_ACTOR4]!=NULL&&strlen(flds[TV_ACTOR4])>0)
	{
		strcat(buf, ", ");
		strcat(buf, flds[TV_ACTOR4]);
	}
	if (nflds>TV_ACTOR5 && flds[TV_ACTOR5]!=NULL&&strlen(flds[TV_ACTOR5])>0)
	{
		strcat(buf, ", ");
		strcat(buf, flds[TV_ACTOR5]);
	}
	if (nflds>TV_ACTOR6 && flds[TV_ACTOR6]!=NULL&&strlen(flds[TV_ACTOR6])>0)
	{
		strcat(buf, ", ");
		strcat(buf, flds[TV_ACTOR6]);
	}
	movie->actors = strdup(buf);

	sprintf(buf, "%s [%s]", movie->title, movie->year);
	p = buf;
	if (strncmp(buf, "A ", 2)==0) p += 2;
	else if (strncmp(buf, "An ", 3) == 0) p += 3;
	else if (strncmp(buf, "The ", 4) == 0) p += 4;

	/* we have removed leading article, now check for non-alphanumeric */
	while (*p != '\0' && !isalnum(*p)) p++;
	loc = bsearch_aptr_prodlist(movies, p);
	if (loc >= 0)
	{ /* already in list, just add this show */
		/* free movie fields */
		free(movie->title);
		free(movie->year);
		/* add this show to the end of the list */
		m = (struct Movie *)movies->item[loc];
		for (sh=m->show; sh->next != NULL; sh=sh->next); /* find tail */
		sh->next = show;	/* add to end of list */
	}
	else
	{ /* first time, add to list */
		bupdate_aptr_prodlist(movies, strdup(p), movie);
	}
}

char *format_tvdate(char *s)
{
	static char ret[BUFSIZ];
	char *p;

	p = ret; /* point to return string */
	*p++ = *s++; /* first digit of month */
	*p++ = *s++; /* second digit of month */
	*p++ = '/';
	*p++ = *s++; /* day of month */
	*p++ = *s++;
	*p++ = '/';
	*p++ = *s++;
	*p++ = *s++;
	*p = '\0';

	return ret;
}


int close_movie_titles(int nchan, char *chans[])
{
	int i, j, c;
	FILE *fp;
	char *ab = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	if ((fp = fopen("movie_chan.html", "w")) == NULL)
	{
		fprintf(stderr, "Can't create movie channel report\n");
		nchan = 0; /* don't report any movies */
	}

	/* create header */
	fprintf(fp, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
	fprintf(fp, "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n");

	fprintf(fp, "<head>\n<title>List of Upcoming Movies</title>\n");
	fprintf(fp,"<style type='text/css'>\n");
	fprintf(fp, "DT { font-weight: bold; color: blue;}\n");
	fprintf(fp, "DD {margin-bottom: .2em;}\n");
	fprintf(fp, "dd.top { font-size: smaller; }\n");
	fprintf(fp, "</style>\n</head>\n");
	fprintf(fp, "<body>\n<h1 id='beg'>List of Upcoming Movies</h1>\n");
	fprintf(fp, "<ul>");
	for (i=0; i<nchan; i++)
	{
		fprintf(fp, "<li><a href='#chan-%d'>Movies on %s</a></li>\n", i, chans[i]);
	}
	fprintf(fp,"</ul>\n");

	/* produce a list of movies for each movie channel being watched */
	for (i=0; i < nchan; i++)
	{ /*loop through movie channels being watched */
		fprintf(fp, "<h2 id='chan-%d'>Movies on %s</h2>\n", i, chans[i]);

#ifdef FIXLATER
		fprintf(fp, "<dl>\n");

		fflush(fp);
		fprintf(fp, "<p>| <a href=\"%s-0\"> # </a>|", chans[i]);
		for (j=0; ab[j]!='\0'; j++)
		{ /* index for each letter */
			c = ab[j];
			fprintf(fp, "<a href=\"#%s-%c\"> %c </a>|", chans[i], c, c);
		}
		fprintf(fp, "</p>\n");
#endif

		for (j=0; j < movies->nitems; j++)
		{
			/************
			printf("Checking movie: [[%s]]\n", ((struct Movie *)movies->item[j])->title);
			  ************/
			if (on_chan(movies->item[j], chans[i]))
			{ /* movie appears on the channel - list it */
				/* create index by first letter */

				print_shows(movies->item[j], chans[i], fp);
			}
		}
		fprintf(fp, "</dl>\n");
	}
	if (nchan > 0)
	{
		fprintf(fp, "</body>\n</html\n");
		fclose(fp); /* close if used */
	}

	return movies->nitems;
}

int on_chan(struct Movie *mov, char *chan)
{ /* determine if this movie appears on this channel */
	struct Show *show;

	for (show = mov->show; show!=NULL; show=show->next)
	{ /* loop through each showing */
		if (strcmp(show->channel, chan)==0) return 1;
	}
	return 0; /* not found on that channel */
}

void print_shows(struct Movie *mov, char *chan, FILE *fp)
{ /* print each time movie appears on channel */
	struct Show *show;
	char buf[BUFSIZ]; /* work area for date key */
	int first;
	char LastChar='\0', FirstChar;

	fflush(fp);

	#ifdef FIXLATER
	/* Should have section for each letter */
	FirstChar = mov->title[0];	/* first character of movie title */
	if (LastChar == '\0')
	{ /* first movie */
		if (isalpha(FirstChar))
		{ /* no non-alphabetic titles */
			fprintf(fp, "<p id='%s-0'>No # Movies</p>\n",  chan);
		}
		else
		{ /* non-alpha title */
			fprintf(fp, "<p id='%s-0'>Non-Alphabetic Movies</p>\n", chan);
		}
		LastChar='0'; /* no longer first movie */
	}
	if (isalpha(FirstChar) && FirstChar!=LastChar)
	{ /* an alpha title */
		if (LastChar=='0') LastChar = 'A';
		else LastChar++;	/* next letter expected */
		/* write places for missing letters */
		for (; LastChar < FirstChar; LastChar++)
		{
			fprintf(fp, "<p id='%s-%c>No %c Movies</p>\n", chan, LastChar, LastChar);
		}
		/* now create header for current letter */
		fprintf(fp, "<p id='%s-%c'>%c Movies\n", chan, FirstChar, FirstChar);
	}
#endif

	show = mov->show; /* first showing of movie */

	fprintf(fp, "<dt>%s (%s) %s</dt>\n",
	        fixhtml(mov->title), mov->year, mov->stars);
	if (mov->desc!=NULL) fprintf(fp, "<dd>\n%s\n</dd>\n", fixhtml(mov->desc));
	if (mov->actors!=NULL && mov->actors[0]!='\0') fprintf(fp, "<dd>Actors:\n%s\n</dd>\n", fixhtml(mov->actors));
	fprintf(fp, "<dd>%s:\n", chan);
	first=1;

	for (show=mov->show; show!=NULL; show=show->next)
	{
		if (strcmp(show->channel, chan)==0)
		{
			if (first) first=0;
			else fprintf(fp, ", ");
			fprintf(fp, "%s %s (%s)", format_tvdate(show->date), show->btime, show->len);
		}
	}

	fprintf(fp, "\n</dd>\n");
	fprintf(fp, "<dd class='top'><a href='#beg'>Top of page</a></dd>\n");
	fflush(fp);
}

void store_by_date(struct Movie *mov, ProdAPtrList *bydate)
{ /* add movie sorted by earliest showing */
	char buf[BUFSIZ];
	struct Show *show;
	struct Movie *ret;

	show = mov->show; /* get earliest listing */
	/* build key - YYMMDD */
	build_datekey(mov->title, show->date, buf);
	ret = bupdate_aptr_prodlist(bydate, strdup(buf), mov);
	if (ret != NULL) printf("Duplicate (%s)\n", buf);
}

void build_datekey(char *title, char *date, char *buf)
{ /* convert MMDDYY to YYMMDD */
	strncpy(buf, date+4, 2);
	strncpy(buf+2, date+2, 2);
	strncpy(buf+4, date, 2);
	buf[6] = ' ';
	strcpy(buf+7, title);
	return;
}

void list_by_date(FILE *fp, ProdAPtrList *bydate)
{ /* list last half of listings by date */
	int i;
	struct Show *show;
	struct Movie *mov;

	fprintf(fp, "----------------- By Date\n");
	fflush(fp);
	for (i=(bydate->nitems)/2; i<bydate->nitems; i++)
	{ /* print shows by date */
		mov = (struct Movie *)bydate->item[i];
		show = mov->show;
		fprintf(fp, "%s (%s) %s %s\n", mov->title, mov->year,
		        mov->stars, format_tvdate(show->date));
	}
}

void write_letter_page(char letter)
{ /* create page for movies starting with specified letter */
	FILE *fp;
	int i;
	struct Movie *movie;
	struct Show *sh;
	char buf[BUFSIZ], c;

	if (letter == '#') sprintf(buf, "movies_0.html");
	else sprintf(buf, "movies_%c.html", letter); /* letter page */
	if ((fp = fopen(buf, "wt")) == NULL)
	{
		perror("Can't create movies.txt");
		return;
	}

	/* print file header */
	if (letter == '#') sprintf(buf, "Non-Alpha");
	else sprintf(buf, "%c", letter);
	fprintf(fp,
	        "<html>\n<head>\n<title>%s Movies This Month</title>\n</head>\n",
	        buf);
	fprintf(fp, "<body>\n<h3><a name='toc'>%s Movies This Month</a></h3>\n", buf);

	/* create index to letters */
	fprintf(fp, "<table border='0' cellspacing='6'><tr>\n");
	if (letter == '#')
	{ /* this page, no link */
		fprintf(fp, "<td>#</td>\n");
	}
	else
	{ /* link to non-alpha page */
		fprintf(fp, "<td><a href='movies_0.html'>#</a></td>\n");
	}
	for (i=0; i<26; i++)
	{
		c = i+'A'; /* next letter */
		if (c == letter)
		{ /* this letter, no link needed */
			sprintf(buf, "<td>%c</td>\n", c);
		}
		else
		{ /* create link to this page */
			sprintf(buf, "<td><a href='movies_%c.html'>%c</a></td>\n", c, c);
		}
		fputs(buf, fp);
	}
	fprintf(fp, "</tr></table>\n");
	fflush(fp);

	/* build index of movies */
	fprintf(fp, "<ul>\n");
	for (i=0; i < movies->nitems; i++)
	{
		movie = (struct Movie *)movies->item[i];
		if (letter == '#') c = movie->title[0];
		else c = movies->key[i][0];
		/*
		if (letter == '#' && isalpha(c)) continue; /* non-alpha page */
		/*
		else if (c != letter) continue; /* different letter */
		if (letter == '#' && isalpha(c)) continue; /* non-alpha page */
		else if (letter != '#' && c != letter) continue; /* different letter */

		/* this movie belongs on this page - write index */
		fprintf(fp, "<li><a href='#m%d'>%s</a> (%s) [%s]</li>\n",
		        i, movie->title, movie->year, movie->desc);
		fputc('\n', fp);
	}
	fprintf(fp, "</ul>\n");

	/* print out detailed schedule */
	fprintf(fp, "<table border='1'>\n");
	for (i=0; i < movies->nitems; i++)
	{
		movie = (struct Movie *)movies->item[i];
		if (letter == '#') c = movie->title[0];
		else c = movies->key[i][0];
		if (letter == '#' && isalpha(c)) continue; /* non-alpha page */
		else if (letter != '#' && c != letter) continue; /* different letter */

		/* this movie belongs on this page - write details */
		fprintf(fp, "<tr><td><a name='m%d'>%s</a> (%s)<br />%s<br /><a href='#toc'>Top</a></td><td>\n",
		        i, movie->title, movie->year, movie->desc);
		/* print trailer */
		fprintf(fp, "<table border='0'>\n");
		for (sh=movie->show; sh != NULL; sh = sh->next)
		{
			fprintf(fp, "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",
			        sh->channel, format_tvdate(sh->date), sh->btime, sh->len);
		}

		fprintf(fp, "</table>\n</td></tr>\n");
	}

	fprintf(fp, "</table>\n</body>\n</html>\n");
	fclose(fp);

}

char *fixhtml(char *txt)
{
	static char buf[4096], *p, *q;

	for (p=txt, q=buf; *p!='\0'; p++)
	{
		if (*p=='&')
		{
			strcpy(q, "&amp;");
			q += 5;
		}
		else *q++ = *p;
	}
	*q = '\0';	/* truncate output string */
	return buf;
}

