#include "squaredance.h"
#include "views.h"

static int chooseFirst(void *data,char **names, int cnt, int is_dance) {
return( 0 );
}

int main(int argc, char **argv) {
    FigureLib *lib;
    Figure *figure;
    char *mpname, *pt, *end;
    int i, j,k, both=0;
    long flags = 0;
    struct video_options options;
    char *outputname=NULL;
    char *extension, *dir;
    char *frameDir = "./Frames/";

    memset(&options,0,sizeof(options));
    options.past_path_millibars = -1;		/* Because 0 is a reasonable value, don't want it to mean default */
    options.future_path_millibars = -1;
    options.music_amplify = 1;
    /* Defaults are handled in danceVideo now */

    for ( i=1 ; i<argc; ++i ) {
	if ( *argv[i]=='-' || *argv[i]=='+' ) {
	    char *pt = argv[i]+1;
	    if ( *pt=='-' )
		++pt;
	    if ( strcmp(pt,"couples")==0 && i+1<argc )
		options.couples = strtol(argv[++i],NULL,10);
	    else if ( strcmp(pt,"out-at-top")==0 && i+1<argc )
		options.out_at_top = strtol(argv[++i],NULL,10);
	    else if ( strcmp(pt,"minorsets")==0 && i+1<argc )
		options.minor_set_count = strtol(argv[++i],NULL,10);
	    else if ( strcmp(pt,"part")==0 && i+1<argc )
		options.initial_part = strtol(argv[++i],NULL,10);
	    else if ( strcmp(pt,"width")==0 && i+1<argc )
		options.width = strtol(argv[++i],NULL,10);
	    else if ( strcmp(pt,"height")==0 && i+1<argc )
		options.height = strtol(argv[++i],NULL,10);
	    else if ( strcmp(pt,"fps")==0 && i+1<argc )
		options.frames_per_sec = strtol(argv[++i],NULL,10);
	    else if ( strcmp(pt,"fpb")==0 && i+1<argc )
		options.frames_per_bar = strtol(argv[++i],NULL,10);
	    else if ( strcmp(pt,"usable")==0 && i+1<argc )
		options.usable_fraction = strtod(argv[++i],NULL);
	    else if ( strcmp(pt,"audio")==0 && i+1<argc ) {
		options.audio_sample_rate = strtol(argv[++i],NULL,10);
		if ( options.audio_sample_rate==0 )
		    options.audio_sample_rate = -1;
	    } else if ( strcmp(pt,"bit-rate")==0 && i+1<argc ) {
		options.vbit_rate = strtol(argv[++i],NULL,10);
	    } else if ( strcmp(pt,"past-path")==0 && i+1<argc )
		options.past_path_millibars = round(1000*strtod(argv[++i],NULL));
	    else if ( strcmp(pt,"future-path")==0 && i+1<argc )
		options.future_path_millibars = round(1000*strtod(argv[++i],NULL));
	    else if ( strcmp(pt,"background")==0 && i+1<argc )
		options.background = argv[++i];
	    else if ( (strcmp(pt,"amplify")==0 || strcmp(pt,"music-amplify")==0) && i+1<argc )
		options.music_amplify = strtod(argv[++i],NULL);
	    else if ( strcmp(pt,"crop")==0 && i+1<argc ) {
		/* w:h:x:y */
		options.crop.width = strtol(argv[++i],&end,10);
		if ( *end==':' ) {
		    options.crop.height = strtol(end+1,&end,10);
		    if ( *end==':' ) {
			options.crop.x = strtol(end+1,&end,10);
			if ( *end==':' )
			    options.crop.y = strtol(end+1,&end,10);
		    }
		} else {
		    fprintf( stderr, " You must specify at least width and height when cropping. w:h:x:y\n" );
exit(1);
		}
	    } else if ( (strcmp(pt,"output")==0 || strcmp(pt,"o")==0 ) && i+1<argc )
		outputname = argv[++i];
	    else if ( strcmp(pt,"callPos")==0 && i+1<argc ) {
		char *a = argv[++i];
		if ( strcasecmp(a,"roomiest")==0 )
		    options.callPos = cp_roomiest;
		else if ( strcasecmp(a,"left")==0 )
		    options.callPos = cp_left;
		else if ( strcasecmp(a,"under")==0 || strcasecmp(a,"below")==0)
		    options.callPos = cp_under;
		else {
		    fprintf( stderr, "callPos must be one of 'roomiest', 'left', or 'under'.\n" );
		    exit(1);
		}
	    } else if ( (strcmp(pt,"music")==0 || strcmp(pt,"m")==0 ) && i+1<argc ) {
		mdFree(options.music);
		options.music = danceLoadMusicDescription(argv[++i]);
	    } else if ( strcmp(pt,"noaudio")==0 ) {
		if ( *argv[i]=='+' )
		    options.audio_sample_rate = -1;
	    } else if ( strcmp(pt,"title")==0 ) {
		flags &= ~((1<<df_title)|(1<<df_noTitle));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_title;
		else
		    flags |= 1<<df_noTitle;
	    } else if ( strcmp(pt,"frameTitle")==0 ) {
		flags &= ~((1<<df_frameTitle)|(1<<df_noFrameTitle));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_frameTitle;
		else
		    flags |= 1<<df_noFrameTitle;
	    } else if ( strcmp(pt,"showBar")==0 ) {
		flags &= ~((1L<<df_showBar)|(1L<<df_noShowBar));
		if ( *argv[i]=='+' )
		    flags |= 1L<<df_showBar;
		else
		    flags |= 1L<<df_noShowBar;
	    } else if ( strcmp(pt,"showFrame")==0 ) {
		flags &= ~((1<<df_showFrame)|(1<<df_noShowFrame));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_showFrame;
		else
		    flags |= 1<<df_noShowFrame;
	    } else if ( strcmp(pt,"showPerson")==0 ) {
		flags &= ~((1<<df_showPerson)|(1<<df_noShowPerson));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_showPerson;
		else
		    flags |= 1<<df_noShowPerson;
	    } else if ( strcmp(pt,"showGrid")==0 ) {
		flags &= ~((1<<df_showGrid)|(1<<df_noShowGrid));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_showGrid;
		else
		    flags |= 1<<df_noShowGrid;
	    } else if ( strcasecmp(pt,"minorset")==0 ) {
		flags &= ~((1<<df_minorSet)|(1<<df_noMinorSet));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_minorSet;
		else
		    flags |= 1<<df_noMinorSet;
	    } else if ( strcasecmp(pt,"showpath")==0 ) {
		flags &= ~((1<<df_showPath)|(1<<df_noShowPath));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_showPath;
		else
		    flags |= 1<<df_noShowPath;
	    } else if ( strcasecmp(pt,"clasp")==0 ) {
		flags &= ~((1<<df_debugClasp)|(1<<df_noDebugClasp));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_debugClasp;
		else
		    flags |= 1<<df_noDebugClasp;
	    } else if ( strcasecmp(pt,"count")==0 ) {
		flags &= ~((1<<df_addCounts)|(1<<df_noAddCounts));
		if ( *argv[i]=='+' ) {
		    flags |= 1<<df_addCounts;
		    flags &= ~(1<<df_addTone);
		} else
		    flags |= 1<<df_noAddCounts;
	    } else if ( strcasecmp(pt,"tone")==0 ) {
		flags &= ~((1<<df_addTone)|(1<<df_noAddTone));
		if ( *argv[i]=='+' ) {
		    flags |= 1<<df_addTone;
		    flags &= ~(1<<df_addCounts);
		} else
		    flags |= 1<<df_noAddTone;
	    } else if ( strcasecmp(pt,"both")==0 ) {
		if ( *argv[i]=='+' )
		    both=1;
		else
		    both=0;
	    } else if ( strcmp(pt,"retain")==0 ) {
		flags &= ~((1<<df_retainFrames)|(1<<df_deleteFrames));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_retainFrames;
		else
		    flags |= 1<<df_deleteFrames;
	    } else if ( strcmp(pt,"append")==0 ) {
		flags &= ~((1<<df_appendFrames)|(1<<df_overwriteFrames));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_appendFrames;
		else
		    flags |= 1<<df_overwriteFrames;
	    } else if ( strcmp(pt,"women")==0 || strcmp(pt,"woman")==0 ) {
		flags &= ~((1<<df_womensOrientation)|(1<<df_mensOrientation));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_womensOrientation;
		else
		    flags |= 1<<df_mensOrientation;
	    } else if ( strcmp(pt,"honour")==0 || strcmp(pt,"honor")==0 ) {
		flags &= ~((1<<df_honour)|(1<<df_noHonour));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_honour;
		else
		    flags |= 1<<df_noHonour;
	    } else if ( strcmp(pt,"verbose")==0 || strcmp(pt,"v")==0 ) {
		flags &= ~((1L<<df_verbose)|(1L<<df_noVerbose));
		if ( *argv[i]=='+' )
		    flags |= 1L<<df_verbose;
		else
		    flags |= 1L<<df_noVerbose;
	    } else if ( strcmp(pt,"png")==0 || strcmp(pt,"pngs")==0 ) {
		flags &= ~((1L<<df_png)|(1L<<df_noPng)|(1L<<df_svg)|(1L<<df_noSvg));
		if ( *argv[i]=='+' )
		    flags |= 1L<<df_png;
		else
		    flags |= 1L<<df_noPng;
	    } else if ( strcmp(pt,"svg")==0 || strcmp(pt,"pngs")==0 ) {
		flags &= ~((1L<<df_png)|(1L<<df_noPng)|(1L<<df_svg)|(1L<<df_noSvg));
		if ( *argv[i]=='+' ) {
		    flags |= 1L<<df_svg;
		    flags &= ~((1L<<df_title)|(1L<<df_minorSet));
		    flags |= (1L<<df_noTitle)|(1L<<df_noMinorSet);
		} else
		    flags |= 1L<<df_noSvg;
	    } else if ( strcasecmp(pt,"sicilian")==0 ) {
		flags &= ~((1<<df_sicilianCircle)|(1<<df_noSicilianCircle));
		if ( *argv[i]=='+' ) {
		    flags |= (1<<df_sicilianCircle) ;
		} else
		    flags |= 1<<df_noSicilianCircle;
	    } else if ( strcasecmp(pt,"sicilianScale")==0 ) {
		flags &= ~((1L<<df_sicilianScale)|(1L<<df_noSicilianScale));
		if ( *argv[i]=='+' ) {
		    flags |= (1L<<df_sicilianScale) ;
		} else
		    flags |= 1L<<df_noSicilianScale;
	    } else if ( strcmp(pt,"open")==0 ) {
		flags &= ~((1<<df_openAfter)|(1<<df_noOpenAfter));
		if ( *argv[i]=='+' )
		    flags |= 1<<df_openAfter;
		else
		    flags |= 1<<df_noOpenAfter;
	    } else if ( strcmp(pt,"old")==0 || strcmp(pt,"oldProgression")==0 ) {
		flags &= ~((1L<<df_oldProgression)|(1L<<df_noOldProgression));
		if ( *argv[i]=='+' )
		    flags |= 1L<<df_oldProgression;
		else
		    flags |= 1L<<df_noOldProgression;
	    } else if ( strcasecmp(pt,"test")==0 ) {
		flags &= ~((1<<df_title)|(1<<df_noDebugClasp)|(1<<df_minorSet)|(1<<df_noOpenAfter)|(1L<<df_noTest)|(1L<<df_noShowBar));
		flags |= (1<<df_noTitle)|(1<<df_debugClasp)|(1<<df_noMinorSet)|(1<<df_openAfter)|(1L<<df_test)|(1L<<df_showBar);
		options.frames_per_sec = 8;
		/*options.frames_per_bar = 8;*/
		options.minor_set_count = 1;
	    } else if ( strcasecmp(pt,"testSlow")==0 ) {
		flags &= ~((1<<df_title)|(1<<df_noDebugClasp)|(1<<df_minorSet)|(1<<df_noOpenAfter)|(1L<<df_noTest));
		flags |= (1<<df_noTitle)|(1<<df_debugClasp)|(1<<df_noMinorSet)|(1<<df_openAfter)|(1L<<df_test)|(1L<<df_showBar);
		options.frames_per_sec = 8;
		options.frames_per_bar = 24;
		options.minor_set_count = 1;
		/* Same as test except very slow */
	    } else if ( strcasecmp(pt,"testDance")==0 ) {
		flags &= ~((1<<df_title)|(1<<df_noDebugClasp)|(1<<df_minorSet)|(1L<<df_noTest));
		flags |= (1<<df_noTitle)|(1<<df_debugClasp)|(1<<df_noMinorSet)|(1<<df_openAfter)|(1L<<df_test)|(1L<<df_showBar);
		options.frames_per_sec = 8;
		/* options.frames_per_bar = 8;*/
		/* Same as test except multiple minor sets */
	    } else if ( strcasecmp(pt,"testMinor")==0 || strcasecmp(pt,"testMinorset")==0 ) {
		flags &= ~((1<<df_title)|(1<<df_noDebugClasp)|(1<<df_noMinorSet)|(1L<<df_noTest));
		flags |= (1<<df_noTitle)|(1<<df_debugClasp)|(1<<df_minorSet)|(1<<df_openAfter)|(1L<<df_test)|(1L<<df_showBar);
		options.frames_per_sec = 8;
		/*options.frames_per_bar = 8;*/
		options.minor_set_count = 1;
		/* Same as test except a demo minor set */
	    } else if ( strcasecmp(pt,"testScot")==0 || strcasecmp(pt,"testScottish")==0 ) {
		flags &= ~((1<<df_noTitle)|(1<<df_noDebugClasp)|(1<<df_noMinorSet)|(1L<<df_noTest));
		flags |= (1<<df_title)|(1<<df_debugClasp)|(1<<df_minorSet)|(1<<df_openAfter)|(1L<<df_test);
		options.frames_per_sec = 8;
		/*options.frames_per_bar = 8;*/
		/* options.minor_set_count = 3; */
		/* Same as test except a demo minor set, and go through the minor set 3 times */
		/* Three times means we expose any problems with scottish */
		/*  progression at the end of the 2nd set */
	    } else if ( strcasecmp(pt,"liveani")==0 ) {
		/* the set of options I want of the animation portion of  a liveani video */
		/* no title, slow minorsets, only twice through, width 1920 */
		flags &= ~((1<<df_title)|(1<<df_noMinorSet));
		flags |= (1<<df_noTitle)|(1<<df_minorSet);
		options.width = 1920; options.height = 1080;
		options.frames_per_sec = 30;
		options.minor_set_count = 2;
		if ( outputname==NULL ) {
		    outputname = strdup("ani.mp4");
		    fprintf( stderr, "Output to 'ani.mp4'\n" );
		}
	    } else if ( strcasecmp(pt,"gif")==0 ) {
		if ( *argv[i]=='+' ) {
		    options.gifOutput = 1;
		    options.frames_per_sec = 10; /* Should divide 100 */
		    options.frames_per_bar = 10;
		    flags &= ~((1L<<df_png)|(1L<<df_noPng)|(1L<<df_svg)|(1L<<df_noSvg));
		    flags |= (1L<<df_png);
		    options.width = 448;
		    options.audio_sample_rate = 0;
		} else
		    options.gifOutput = 0;
	    } else if ( strcasecmp(pt,"fb")==0 ) {
		flags &= ~((1<<df_title)|(1<<df_debugClasp)|(1<<df_minorSet));
		flags |= (1<<df_noTitle)|(1<<df_noDebugClasp)|(1<<df_noMinorSet);
		options.minor_set_count = 2;
	    } else if ( strcmp(pt,"titleFrames")==0 && i+1<argc ) {
		options.titleframes = strtol(argv[++i],NULL,10);
	    } else if ( strcmp(pt,"musicTitleFrames")==0 && i+1<argc ) {
		options.musictitleframes = strtol(argv[++i],NULL,10);
	    } else if ( strcmp(pt,"frameDir")==0 && i+1<argc ) {
		frameDir = argv[++i];
	    } else {
		fprintf( stderr, "Unknown argument: %s\n", argv[i] );
		fprintf( stderr, "Usage %s [-couples nn] [-minorsets nn] [-width nnnn] [-fps nn] [-fpb nn] [-usable .n] [{-+}title] [{-+}minorset] [{-+}showPath] [{-+}showFrame] [{-+}clasp] [{-+}both] [{-+}test] filenames\n", argv[0] );
exit( 1 );
	    }
    continue;
	}
	/* figure = danceLoadFigure(argv[i],chooseFirst,NULL);*/
	lib = danceLoadLibrary(argv[i]);
	if ( lib==NULL ) {
	    char *msg = danceLoaderError();
	    if ( msg==NULL )
		fprintf( stderr, "Failed to load %s, unknown reason.\n", argv[i] );
	    else
		fprintf( stderr, "%s\n", msg);
exit(1);
	} else if ( lib->figures==NULL || lib->figures[0]==NULL ) {
	    fprintf( stderr, "Empty library: %s\n", argv[i] );
	    figureLibFree(lib);
    continue;
	}
	extension = "mp4";
	dir = "/tmp";
	if ( flags&(1L<<df_svg) ) {
	    extension = "html";
	    dir = ".";
	} else if ( options.gifOutput )
	    extension = "gif";
	if ( flags&(1L<<df_test) && outputname==NULL ) {
	    static int test_cnt=1;
	    char buffer[40];
	    if ( test_cnt==1 )
		sprintf( buffer, "%s/test.%s", dir, extension );
	    else
		sprintf( buffer, "%s/test%d.%s", dir, test_cnt, extension );
	    outputname = strdup(buffer);	/* Memory leak */
	    ++test_cnt;
	}
	for ( j=0; lib->figures[j]!=NULL; ++j ) {
	    figure = lib->figures[j];
	    for ( k=0; k<1+both; ++k ) {
		if ( outputname!=NULL && !(flags&(1<<df_retainFrames)) ) {
		    mpname = strdup(outputname);
		    outputname = NULL;
		} else {
		    mpname = malloc(strlen(argv[i])+20 + strlen(figure->name) + strlen("-showpath"));
		    strcpy(mpname,argv[i]);
		    pt = strrchr(mpname,'.');
		    if ( pt==NULL || pt<strrchr(mpname,'/') )
			pt = mpname+strlen(mpname);
		    if ( k==1 ) {
			strcpy(pt,"-showpath");
			pt += strlen(pt);
		    }
		    if ( lib->figures[1]!=NULL ) {
			*pt++ = '-';
			strcpy(pt,figure->name);
			while ( *pt ) {
			    if ( *pt==' ' )
				*pt='-';
			    ++pt;
			}
		    }
		    *(pt++) = '.';
		    strcpy(pt,extension);
		}
		if ( both==0 )
		    options.flags = flags;
		else if ( k==0 )
		    options.flags = (flags&~df_showPath)|df_noShowPath;
		else
		    options.flags = (flags&~df_noShowPath)|df_showPath;
		danceMakeVideo(figure,&options, mpname,frameDir);
		free(mpname);
	    }
	}
	figureLibFree(lib);
    }
    if ( argc==1 ) {
	fprintf( stderr, "No arguments.\nUsage: %s foo.dance\n", argv[0] );
return( 1 );
    }

return(0);
}
