#include <stdio.h>
#include <stdlib.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <string.h>
#include <strings.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

struct vclips_s {
	char *src;
	int msbeg;
	int msend;
} vclips[1000];

int skip[8000];

int cnum=-1;

char *extsrc, extsrcdef[]="m2ts";
char *extpro, extprodef[]="dv";

int docmd(char *s){
    printf("$ %s\n",s);
    return system(s);
}

parse_kino_xml(xmlNode *node){
	xmlNode *a;
	for(a=node;a;a=a->next){
		if(a->type==XML_ELEMENT_NODE){
			if(!strcasecmp(a->name,"video")){
				char *p;
				if(p=xmlGetProp(a,"src")){
					int l=strlen(p);
					char *r=rindex(p,'.');
					char *q=malloc(l+5);
					strncpy(q,p,(r-p)+1);
					strcpy(q+(r-p)+1,extsrc);
					vclips[++cnum].src=q;
				}
				if(p=xmlGetProp(a,"clipBegin")){
					int thr,tmi,tse,tms;
					sscanf(p,"%d:%d:%d.%d",&thr,&tmi,&tse,&tms);
					vclips[cnum].msbeg=tms+60*(tse+60*(tmi+60*thr));
				} 
				if(p=xmlGetProp(a,"clipEnd")){
					int thr,tmi,tse,tms,tot;
					sscanf(p,"%d:%d:%d.%d",&thr,&tmi,&tse,&tms);
					vclips[cnum].msend=tms+60*(tse+60*(tmi+60*thr));
				}
			}
		}
		parse_kino_xml(a->children);
	}
}

int main(int argc, char **argv){
	int i;
	char *filename,*outfile;
	int opt;
	xmlDoc *doc = 0;
	xmlNode *node = 0;
	LIBXML_TEST_VERSION
	puts("k264mux -- convert kino xml file to tsmuxer meta files\n"
		"Version 2 August 2009 by Eric Olson GNU License.\n");
	extpro=extprodef;
	extsrc=extsrcdef;
	while((opt=getopt(argc,argv,"p:s:h")) != -1){
		switch(opt){
		case 'p':
			{
				extpro=optarg;
				printf( "Setting extension of proxy files to %s.\n",
					extpro);
			}
			break;
		case 's':{
				extsrc=optarg;
				printf( "Setting extension of source files to %s.\n",
					extsrc);
			}
			break;
		case '?':
		case 'h':
			printf("Usage k264mux [options] filename.xml\n"
				"where options are\n"
				"\t-p ext   Extension of the proxy files (%s)\n"
                   "\t-s ext   Extension of the source files (%s)\n"
				"\t-h       Display this message.\n",
				extprodef,extsrcdef);
			exit(2);
			break;
		}
	}
	argc-=optind-1;
	argv+=optind-1;
	if (argc != 2) {
		fprintf(stderr,"Need a kino xml file!\n");
		exit(1);
	}
	filename=argv[1];
	{
		int l=strlen(filename);
		char *r=rindex(filename,'.');
		outfile=malloc(l+5);
		strncpy(outfile,filename,r-filename);
		strcpy(outfile+(r-filename),".ts");
	}
	doc = xmlReadFile(filename, NULL, 0);
	if(!doc){
		fprintf(stderr,"Failed to parse %s!\n", filename);
		exit(2);
	}
	node=xmlDocGetRootElement(doc);
	parse_kino_xml(node); cnum++;
/*
MUXOPT --no-pcr-on-video-pid --new-audio-pes --vbr  --cut-start=5ms --cut-end=8ms --vbv-len=500
V_MPEG4/ISO/AVC, "/home/ejolson/cfaith/bellamoe/fix.m2ts", fps=29.970, insertSEI, contSPS, track=4113
A_AC3, "/home/ejolson/cfaith/bellamoe/fix.m2ts", track=4352
*/
	for(i=0;i<cnum;i++){
		FILE *fp;
		char metanm[64];
		sprintf(metanm,"mux%03d.meta",i);
		fp=fopen(metanm,"w");
		fprintf(fp,
"MUXOPT --no-pcr-on-video-pid --new-audio-pes --vbr  --cut-start=%dms --cut-end=%dms --vbv-len=500\n"
"V_MPEG4/ISO/AVC, \"%s\", fps=29.970, insertSEI, contSPS, track=4113\n"
"A_AC3, \"%s\", track=4352\n",
			vclips[i].msbeg,vclips[i].msend,
			vclips[i].src,vclips[i].src);
		fclose(fp);
	}
	for(i=0;i<cnum;i++){
		char metanm[64],tsnm[64],scmd[64];
		sprintf(metanm,"mux%03d.meta",i);
		sprintf(tsnm,"mux%03d.m2ts",i);
		sprintf(scmd,"tsMuxeR %s %s",metanm,tsnm);
		docmd(scmd);
		{
			struct stat sbuf;
			stat(tsnm,&sbuf);
			if(!sbuf.st_size) skip[i]=1;
		}
	}
	while(cnum>0 && skip[cnum-1]) cnum--;
	{
		FILE *fp;
		fp=fopen("muxjoin.meta","w");
		fprintf(fp,
"MUXOPT --no-pcr-on-video-pid --new-audio-pes --vbr  --vbv-len=500\n"
"V_MPEG4/ISO/AVC, ");
		for(i=0;i<cnum;i++){
			if(!skip[i]){
				char tsnm[64];
				sprintf(tsnm,"mux%03d.m2ts",i);
				fprintf(fp,"\"%s\"%c",tsnm,i+1!=cnum?'+':',');
			}
		}
		fprintf(fp," fps=29.970, insertSEI, contSPS, track=4113\n");
		fprintf(fp,"A_AC3, ");
		for(i=0;i<cnum;i++){
			if(!skip[i]){
				char tsnm[64];
				sprintf(tsnm,"mux%03d.m2ts",i);
				fprintf(fp,"\"%s\"%c",tsnm,i+1!=cnum?'+':',');
			}
		}
		fprintf(fp," timeshift=67ms, track=4352\n");
		fclose(fp);
	}
	{
		char cmd[1024];
		sprintf(cmd,"tsMuxeR muxjoin.meta %s",outfile);
		docmd(cmd);
	}
	xmlFreeDoc(doc);
    xmlCleanupParser();
}
