#include "views.h"
#include <assert.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>

static int countDir(char *framedir) {
    int biggest=0, cur;
    DIR *dir;
    struct dirent *f;
    char *pt;

    dir = opendir(framedir);
    if ( dir==NULL )
return(0);

    while ( (f=readdir(dir))!=NULL ) {
	if ( f->d_name[0]!='D' )
    continue;
	if ( !isdigit(f->d_name[1]))
    continue;
	pt = strrchr(f->d_name,'.');
	if ( pt==NULL )
    continue;
	if ( strcmp(pt,".png")!=0 )
    continue;
	cur = strtol(f->d_name+1,NULL,10);
	if ( cur>biggest )
	    biggest = cur;
    }
    closedir(dir);
return( biggest );
}

static void danceFork(DanceView *dv, Comparison *comp, struct video_options *options,
	char *framedir, int which ) {
    char *myframedir = malloc( strlen(framedir)+10 );
    char *buffer;
    char minorsetcount[64];

    sprintf( myframedir, "%s/%d/", framedir, which );
    dv->framedirs[which] = myframedir;
    mkdir(myframedir,0755);
    removePngs(myframedir);
    dv->framedirs[which] = myframedir;

    buffer=malloc(strlen(comp->dances[which].filename) + 1000);
    if ( options->minor_set_count!=0 )
	sprintf( minorsetcount, "-minorsets %d ", options->minor_set_count );
    else
	minorsetcount[0]='\0';
    sprintf( buffer, "./d2v +png +retain -frameDir %s %s%s%s%s%s%s%s-fps %d -titleFrames %d -musicTitleFrames %d -width %d -height %d %s %s\n",
	    myframedir,
	    options->flags & (1L<<df_test) ? "+test " : "",
	    options->flags & (1L<<df_showFrame) ? "+showFrame " : "",
	    options->flags & (1L<<df_noMinorSet) ? "-minorset " : "",
	    options->flags & (1L<<df_noTitle) ? "-title " : "",
	    options->flags & (1L<<df_title) ? "+title " : "",
	    minorsetcount,
	    comp->dances[which].sicilian==0 ? "-sicilian " : comp->dances[which].sicilian==1 ? "+sicilian " : "",
	    dv->frames_per_sec,
	    options->titleframes,
	    options->musictitleframes,
	    comp->stacked_vertically ? dv->width : dv->width/2,
	    comp->stacked_vertically ? dv->height/2 : dv->height,
	    comp->dances[which].args,
	    comp->dances[which].filename );
 printf( "%s\n", buffer );
    system( buffer );
    free(buffer);
    dv->biggestframe[which] = countDir(myframedir);
}

void danceMakeComparison(Comparison *comp, struct video_options *options,
	char *filename, char *framedir) {
    DanceView *dv;
    PangoRectangle r;
    cairo_surface_t *origImage;
    cairo_surface_t *v1, *v2;
    int i, yorig;
    int frames;

    dv = calloc(1,sizeof(DanceView));
    dv->dance= (Dance *) comp;
    if ( options->audio_sample_rate==0 )
	dv->audio_sample_rate = 44100;
    else if ( options->audio_sample_rate<0 )
	dv->audio_sample_rate = 0;
    else
	dv->audio_sample_rate = options->audio_sample_rate;
    dv->vbit_rate = options->vbit_rate;

    dv->filename = filename;
    dv->framedir = framedir;
    if ( options->width!=0 )
	dv->width = options->width;
    else if ( options->height!=0 )
	dv->width = (16*dv->height)/9;
    else
	dv->width = 1280;
    if ( options->height==0 )
	dv->height = (9*dv->width)/16;
    else
	dv->height = options->height;
    if ( options->usable_fraction==0 )
	dv->usable_fraction = .9;
    else
	dv->usable_fraction = options->usable_fraction;
    danceFigureTitleFrames(dv, comp, options );

    danceFork(dv,comp,options,framedir,0);
    danceFork(dv,comp,options,framedir,1);

    dv->show_title = true;
    dv->show_frameTitle = false;
    if ( options->flags&(1<<df_noTitle) )
	dv->show_title = false;
    if ( options->flags&(1L<<df_verbose))
	dv->verbose = true;
    else if ( options->flags&(1L<<df_noVerbose))
	dv->verbose = false;
    comp->dance.verbose = dv->verbose;


    dv->stereo_output = true;
    danceAVStart(dv, options);
    danceAVBuildComparisonTimelines(dv, options);
    dv->active = dv->timeline;

    dv->frame = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
	    dv->width, dv->height);
    dv->cr = cairo_create(dv->frame);

/* Display title */
    if ( dv->active->timeline_type==tl_title ) {
	PangoFontDescription *font;
	double fontFactor;
	char *temp, *pt;

	dv->layout = pango_cairo_create_layout(dv->cr);
	fontFactor = dv->width / (dv->height*16/9.0);
	if ( fontFactor>.9 ) fontFactor = 1;
	font = pango_font_description_new();
	pango_font_description_set_family(font,"Adobe Caslon Pro,times,serif");
	pango_font_description_set_size(font,dv->height*48*fontFactor*PANGO_SCALE/1080);

	cairo_set_source_rgb(dv->cr, 1.0,.94,.87 );
	cairo_paint(dv->cr);

	pango_font_description_set_size(font,dv->height*40*fontFactor*PANGO_SCALE/1080);
	pango_layout_set_font_description(dv->layout,font);
	temp = quoteCvt(dv->dance->name,true);
	if ( (pt=strchr(temp,'\n'))!=NULL )		/* This is for titles with a subtitle (Three's company): Don't show the subtitle here */
	    *pt='\0';
	pango_layout_set_markup(dv->layout,temp,-1);
	free(temp);
	pango_layout_get_pixel_extents(dv->layout,NULL,&r);
	cairo_move_to(dv->cr,(dv->width-r.width)/2,r.height);
	cairo_set_source_rgb(dv->cr, 0,0,0 );
	pango_cairo_show_layout(dv->cr,dv->layout);
	pango_layout_set_attributes(dv->layout,NULL);
	yorig = 2*r.height;

	if ( comp->sourceImage != NULL ) {
	    origImage = cairo_image_surface_create_from_png(comp->sourceImage);
	    if ( origImage!=NULL ) {
		int w, h, vw, vh;
		double hscale, vscale;
		w = cairo_image_surface_get_width(origImage);
		h = cairo_image_surface_get_height(origImage);
		vw = dv->width * dv->usable_fraction;
		vh = dv->height * dv->usable_fraction * .8 /* Leave room for text */;
		vscale = vh / (double) h;
		hscale = vw / (double) w;
		if ( vscale<hscale )
		    hscale = vscale;
		cairo_save(dv->cr);
		cairo_scale(dv->cr,hscale,hscale);
		cairo_set_source_surface(dv->cr,origImage,(dv->width-w*hscale)/2/hscale,yorig/hscale);

		cairo_rectangle(dv->cr,(dv->width-w*hscale)/2/hscale,yorig/hscale,w,h);
		cairo_fill(dv->cr);
		yorig += hscale*h +10;
		cairo_surface_destroy(origImage);
		cairo_restore(dv->cr);
		if ( comp->imageCopyright!=NULL ) {
		    pango_font_description_set_size(font,dv->height*30*fontFactor*PANGO_SCALE/1080);
		    cairo_set_source_rgb(dv->cr, 0,0,0 );
		    pango_layout_set_font_description(dv->layout,font);
		    pango_layout_set_width(dv->layout,w*hscale*PANGO_SCALE);
		    pango_layout_set_wrap(dv->layout,PANGO_WRAP_WORD);
		    pango_layout_set_text(dv->layout,comp->imageCopyright,-1);
		    cairo_move_to(dv->cr,(dv->width-w*hscale)/2,yorig);
		    pango_cairo_show_layout(dv->cr,dv->layout);
		    pango_layout_set_width(dv->layout,-1);
		    pango_layout_set_attributes(dv->layout,NULL);
		    yorig += 2*r.height;
		}
	    }
	}

	cairo_set_source_rgb(dv->cr, 0,0,0 );
	pango_font_description_set_size(font,dv->height*20*fontFactor*PANGO_SCALE/1080);
	pango_layout_set_font_description(dv->layout,font);
	if ( comp->stacked_vertically )
	    pango_layout_set_text(dv->layout,"(audio for the top video is in the left channel, for the bottom the right, adjust the balance to pick one)",-1);
	else
	    pango_layout_set_text(dv->layout,"(audio for the left video is in the left channel, for the right video the right channel, adjust the balance to pick one)",-1);
	pango_layout_set_width(dv->layout,dv->width*dv->usable_fraction*PANGO_SCALE);
	pango_layout_set_wrap(dv->layout,PANGO_WRAP_WORD);
	pango_layout_get_pixel_extents(dv->layout,NULL,&r);
	cairo_move_to( dv->cr, dv->width * (1-dv->usable_fraction)/2, dv->height-1.5*r.height);
	pango_cairo_show_layout(dv->cr,dv->layout);

	frames = dv->active->end_frame - dv->active->start_frame;
	for ( i=0; i<frames; ++i ) {
	    ++dv->title_frame_offset;
	    danceAVAddVideoFrame(dv,0);
	}
	dv->active = dv->active->next;

	pango_font_description_free(font);
	g_object_unref(G_OBJECT(dv->layout));
    }

/* And now the body of the comparison */
    frames = dv->biggestframe[0];
    if ( dv->biggestframe[1]>frames )
	frames = dv->biggestframe[1];
    for ( i=0; i<frames; ++i ) {
	char buffer[400];
	if ( i<=dv->biggestframe[0] )
	    sprintf( buffer, "%s/D%06d.png", dv->framedirs[0], i );
	else
	    sprintf( buffer, "%s/D%06d.png", dv->framedirs[0], dv->biggestframe[0] );
	v1 = cairo_image_surface_create_from_png(buffer);
	
	if ( i<=dv->biggestframe[1] )
	    sprintf( buffer, "%s/D%06d.png", dv->framedirs[1], i );
	else
	    sprintf( buffer, "%s/D%06d.png", dv->framedirs[1], dv->biggestframe[1] );
	v2 = cairo_image_surface_create_from_png(buffer);

	if ( comp->stacked_vertically ) {
	    cairo_set_source_surface(dv->cr,v1,0,0);
	    cairo_rectangle(dv->cr,0,0,
		    cairo_image_surface_get_width(v1), cairo_image_surface_get_height(v1));
	    cairo_fill(dv->cr);
	    yorig = cairo_image_surface_get_height(v1);

	    cairo_set_source_surface(dv->cr,v2,0,yorig);
	    cairo_rectangle(dv->cr,0,yorig,
		    cairo_image_surface_get_width(v2), cairo_image_surface_get_height(v2));
	    cairo_fill(dv->cr);
	    cairo_surface_destroy(v1);
	    cairo_surface_destroy(v2);
	    cairo_set_source_rgb(dv->cr,0,0,0);
	    cairo_set_line_width(dv->cr,3);
	    cairo_move_to(dv->cr,0,yorig);
	    cairo_line_to(dv->cr,dv->width,yorig);
	    cairo_stroke(dv->cr);
	} else {
	    int xorig;
	    cairo_set_source_surface(dv->cr,v1,0,0);
	    cairo_rectangle(dv->cr,0,0,
		    cairo_image_surface_get_width(v1), cairo_image_surface_get_height(v1));
	    cairo_fill(dv->cr);
	    xorig = cairo_image_surface_get_width(v1);

	    cairo_set_source_surface(dv->cr,v2,xorig,0);
	    cairo_rectangle(dv->cr,xorig,0,
		    cairo_image_surface_get_width(v2), cairo_image_surface_get_height(v2));
	    cairo_fill(dv->cr);
	    cairo_surface_destroy(v1);
	    cairo_surface_destroy(v2);
	    cairo_set_source_rgb(dv->cr,0,0,0);
	    cairo_set_line_width(dv->cr,3);
	    cairo_move_to(dv->cr,xorig,0);
	    cairo_line_to(dv->cr,xorig,dv->height);
	    cairo_stroke(dv->cr);
	}
	danceAVAddVideoFrame(dv,i);
    }
    if ( (frames+dv->title_frame_offset)&1 )
	danceAVAddVideoFrame(dv,i); /* I like an even number of frames */

    danceAVFinish(dv,options);

    cairo_destroy(dv->cr);
    cairo_surface_destroy(dv->frame);
}

