/*
 * Copyright 1988, 1989, 1990, 1991 Massachusetts Institute of Technology
 */
#include"../../Glib/Glib.h"
#include"../../GlibExt/GSample.h"
#include<stdio.h>

Server *serv;
int cur_volume = 0, sync_mode = SYNC_MODE;
char frameinput[1000], speedinput[1000];

int DEBUG;

main(argc, argv)
     int argc;
     char **argv;
{
    char temp[1000], *getenv(), *server_string = NULL, arg0[100], arg1[100], 
    arg2[100], arg3[100], arg4[100], arg5[100], *file_string = NULL,
    lastcom[1000], cur_vol_string[30];
    int i, ret, num_args, cur_speed = 0, cur_vol = 0, move_frames, direction,
    start_frame, source_vol;
    FILE *fp;
    
    if (isatty(0) == 0) file_string = "-";
    
    for (i = 1; i < argc; i++) {
	if (strcmp(argv[i], "debug") == 0) DEBUG = 1;
	else if (strcmp(argv[i], "-debug") == 0) DEBUG = 1;
	else if (strcmp(argv[i], "-server") == 0) server_string = argv[++i];
	else if (strcmp(argv[i], "-file") == 0) file_string = argv[++i];
	else if (strcmp(argv[i], "-f") == 0) file_string = argv[++i];
	else printf("Ignoring unknown option: %s\n",argv[i]);
    }
    
    GSetState((int)DEBUG, NULL, sync_mode);
    serv = GNewOpenServer(server_string);
    if (serv == NULL) {
	if (GOpenedHost())
	    fprintf(stderr,"Could not open Galatea server on '%s'\n",
		    GOpenedHost());
	else {
	    fprintf(stderr, "Could open Galatea server due to internal failure\n");
	    fprintf(stderr, 
		    "This failure is probably due to an incorrectly formatted GALATEA environment variable\n");
	}
	exit(2);
    }
    if (file_string == NULL) {
	printf("Use the command 'list' to see available volumes.\n");
	printf("Use the command 'help' to see available commands.\n");
	
	list_volumes(serv);
	fp = stdin;
    }
    if (file_string) {
	if (strcmp(file_string, "-") == 0) fp = stdin;
	else {
	    fp = fopen(file_string, "r");
	    if (fp == NULL) {
		fprintf(stderr, "Unable to open script file: %s\n", file_string);
		exit(1);
	    }
	}
    }
    if (GNumberVolumes(serv) > 0)
	strcpy(cur_vol_string, GVolumeName(serv, 0));
    else
	strcpy(cur_vol_string, "No Volumes available");
    while(1) {
	if (file_string == NULL) {
	    printf("Command [%s]> ", cur_vol_string);
	}
	temp[0] = '\0';
	if (fgets(temp, 1000, fp) == NULL) exit(0);
	if (strncmp(temp, "!!",2) == 0) {
	    strcpy(temp, lastcom);
	    if (!file_string) printf("%s",temp);
	}
	strcpy(lastcom, temp);
	num_args = 
	    sscanf(temp, "%s %s %s %s %s", arg0, arg1, arg2, arg3, arg4, arg5);
	if (num_args == 0) exit(0);
	if (strcmp(arg0, "search") == 0) {
	    if (DEBUG) fprintf(stderr, "Search to frame %d on volume %d...",
			       atoi(arg1), cur_vol);
	    ret = GSearch(serv, cur_vol, atoi(arg1), ALL_CHAN);
	    if (DEBUG) fprintf(stderr, "done\n");
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    else if (!file_string) printf("Current frame number = %d\n",ret);
	    GRelease(serv);
	}
	if (strcmp(arg0, "switch") == 0) {
	    if (DEBUG) fprintf(stderr, "Finding volume index for volume %s...",arg1);
	    cur_vol = GWhichVolumeIndex(serv, arg1);
	    if (DEBUG) fprintf(stderr, "done\nIndex number is %d\n", cur_vol);
	    if (DEBUG) fprintf(stderr, "Switching to volume %d...", cur_vol);
	    ret = GSwitch(serv, cur_vol, ALL_CHAN);
	    if (DEBUG) fprintf(stderr, "done\n");
	    GRelease(serv);
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    else strcpy(cur_vol_string, arg1);
	}
	if (strcmp(arg0, "index") == 0) {
	    if (num_args > 1 && strcmp(arg1, "off") == 0) {
		if (DEBUG) fprintf(stderr, 
				   "Turning off index numbers on volume %d...",
				   cur_vol);
		ret = GConfigure(serv, cur_vol, INDEX_CTRL, TURN_OFF);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
	    }
	    else {
		if (DEBUG) fprintf(stderr, 
				   "Turning on index numbers on volume %d...",
				   cur_vol);
		ret = GConfigure(serv, cur_vol, INDEX_CTRL, TURN_ON);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
	    }
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	}
	if (strcmp(arg0, "squelch") == 0) {
	    if (num_args > 1 && strcmp(arg1, "off") == 0) {
		if (DEBUG) fprintf(stderr, 
				   "Turning off squelch on volume %d...",
				   cur_vol);
		ret = GConfigure(serv, cur_vol, SQUELCH_CTRL, TURN_OFF);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
	    }
	    else {
		if (DEBUG) fprintf(stderr, 
				   "Turning on squelch on volume %d...",
				   cur_vol);
		ret = GConfigure(serv, cur_vol, SQUELCH_CTRL, TURN_ON);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
	    }
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	}
	if (strcmp(arg0, "video") == 0) {
	    if (num_args > 1 && strcmp(arg1, "off") == 0) {
		if (DEBUG) fprintf(stderr, 
				   "Turning off video on volume %d...",
				   cur_vol);
		ret = GConfigure(serv, cur_vol, VIDEO_CHAN, TURN_OFF);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
	    }
	    else {
		if (DEBUG) fprintf(stderr, 
				   "Turning on video on volume %d...",
				   cur_vol);
		ret = GConfigure(serv, cur_vol, VIDEO_CHAN, TURN_ON);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
	    }
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	}
	if (strcmp(arg0, "stop") == 0) {
	    if (DEBUG) fprintf(stderr, "Stopping volume %d...", cur_vol);
	    ret = GRun(serv, cur_vol, 0, ALL_CHAN);
	    if (DEBUG) fprintf(stderr, "done\n");
	    GRelease(serv);
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	}
	if (strcmp(arg0, "play") == 0) {
	    if (num_args == 1) {
		cur_speed = 30;
		if (DEBUG) fprintf(stderr, "Playing volume %d at %d fps...", cur_vol,
				   cur_speed);
		ret = GRun(serv, cur_vol, cur_speed, ALL_CHAN);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
		if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
		else if (!file_string) printf("Playing at %d fps\n",ret);
	    }
	    if (num_args == 2) {
		cur_speed = atoi(arg1);
		if (DEBUG) fprintf(stderr, "Playing volume %d at %d fps...", cur_vol,
				   cur_speed);
		ret = GRun(serv, cur_vol, cur_speed, ALL_CHAN);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
		if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
		else if (!file_string) printf("Playing at %d fps\n",ret);
	    }
	    if (num_args == 3) {
		cur_speed = atoi(arg1);
		if (DEBUG) 
		    fprintf(stderr,"Playing volume %d at %d fps, starting at frame %d...", 
			    cur_vol,  cur_speed, atoi(arg2));
		GSearch(serv, cur_vol, atoi(arg2), NULL);
		ret = GRun(serv, cur_vol, cur_speed, ALL_CHAN);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
		if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
		else if (!file_string) printf("Playing at %d fps\n",ret);
	    }
	    if (num_args == 4) {
		cur_speed = atoi(arg1);
		if (DEBUG)
		    fprintf(stderr,"Playing volume %d at %d fps, starting at frame %d, ending at frame %d...", 
			    cur_vol,  cur_speed, atoi(arg2), atoi(arg3));
		ret = GPlaySeg(serv, cur_vol, atoi(arg2), atoi(arg3), 
			       cur_speed, ALL_CHAN, RETURN_NOW);
		if (DEBUG) fprintf(stderr, "done\n");
		GRelease(serv);
		if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
		else if (!file_string) printf("Started playing at frame %d\n",ret);
	    }
	}
	if (strcmp(arg0, "sleep") == 0) {
	    if (DEBUG) fprintf(stderr, "Sleeping for %d seconds...", atoi(arg1));
	    if (num_args == 1) sleep(1);
	    else sleep(atoi(arg1));
	    if (DEBUG) fprintf(stderr, "done\n");
	}
	if (strcmp(arg0, "echo") == 0) {
	    if (DEBUG) fprintf(stderr, "Echoing...");
	    if (strlen(temp) > 5) printf("%s\n",temp+5);
	    if (DEBUG) fprintf(stderr, "done.");
	}		  
	if (strcmp(arg0, "quit") == 0)
	    exit(0);
	if (strcmp(arg0, "jog") == 0) {
	    if (num_args == 1) {
		move_frames = 1;
	    }
	    if (num_args == 2) {
		if (strcmp(arg1, "up") == 0 || strcmp(arg1, "forward") == 0) {
		    move_frames = 1;
		}
		else if (strcmp(arg1, "down") == 0 || strcmp(arg1, "reverse") == 0) {
		    move_frames = -1;
		}
		else if (arg1[0] == '+' || arg1[0] == '-') {
		    move_frames = atoi(&(arg1[1]));
		    if (arg1[0] == '-') move_frames *= -1;
		}
		else {
		    move_frames = atoi(arg1);
		}
	    }
	    if (DEBUG) fprintf(stderr, "Jogging %d frames on volume %d...",
			       move_frames, cur_vol);
	    if (move_frames < 0) direction = REVERSE;
	    else direction = FORWARD;
	    for (i = 0; i < abs(move_frames); i++)
		ret = GJog(serv, cur_vol, direction, ALL_CHAN);
	    if (DEBUG) fprintf(stderr, "done\n");
	    GRelease(serv);
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    else if (!file_string) printf("Current frame number = %d\n",ret);
	}
	if (strcmp(arg0, "lock") == 0) {
	    if (DEBUG) fprintf(stderr, "Locking server...");
	    GLock(serv);
	    if (DEBUG) fprintf(stderr, "done\n");
	}
	if (strcmp(arg0, "unlock") == 0) {
	    if (DEBUG) fprintf(stderr, "Unlocking server...");
	    GUnLock(serv);
	    if (DEBUG) fprintf(stderr, "done\n");
	}
	if (strcmp(arg0, "alloc") == 0) {
	    if (DEBUG) fprintf(stderr, "Requesting frame allocation...");
	    ret = start_frame = GAlloc(serv, cur_vol, atoi(arg1));
	    if (DEBUG) fprintf(stderr, "done\n");
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    if (!file_string) 
		printf("Allocated %d frames starting at %d\n",atoi(arg1),start_frame);
	}
	if (strcmp(arg0, "allocat") == 0) {
	    if (DEBUG) fprintf(stderr, "Requesting frame allocation at...");
	    ret = start_frame = GAllocAtFrame(serv, cur_vol, atoi(arg1), atoi(arg2));
	    if (DEBUG) fprintf(stderr, "done\n");
	    if (!file_string) 
		printf("Allocated %d frames starting at %d\n",atoi(arg2),start_frame);
	}
	if (strcmp(arg0, "free") == 0) {
	    if (DEBUG) fprintf(stderr, "Freeing frames...");
	    ret = GFree(serv, cur_vol, atoi(arg1), atoi(arg2));
	    if (DEBUG) fprintf(stderr, "done\n");
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    if (!file_string) 
		printf("Freed %d frames starting at %d\n",atoi(arg2), atoi(arg1));
	}
	if (strcmp(arg0, "record") == 0) {
	    if (DEBUG) fprintf(stderr, "Recording...");
	    source_vol = GWhichVolumeIndex(serv, arg3);
	    ret = GRecord(serv, cur_vol, atoi(arg1), atoi(arg2), 30, ALL_CHAN, 
			  source_vol, RETURN_SYNC);
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    if (DEBUG) fprintf(stderr, "done\n");
	    if (!file_string) 
		printf("Recorded from %s to frames %d to %d on %s\n",arg3,
		       atoi(arg1), atoi(arg2), GWhichVolumeName(serv, cur_vol));
	    GRelease(serv);
	}
	if (strcmp(arg0, "preview") == 0) {
	    if (DEBUG) fprintf(stderr, "Setting to record preview...");
	    ret = GRecordPreview(serv, cur_vol, GWhichVolumeIndex(serv,arg1), 
				 ALL_CHAN);
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    if (DEBUG) fprintf(stderr, "done\n");
	    if (!file_string) 
		printf("Record preview from %s to %s\n",arg1,
		       GWhichVolumeName(serv, cur_vol), ALL_CHAN);
	    GRelease(serv);
	}
	if (strcmp(arg0, "sample") == 0) {
	    if (DEBUG) fprintf(stderr, "Trying Sample Extension...");
	    if (num_args == 1)
		ret = GSampleMethod(serv, 0);
	    else ret = GSampleMethod(serv, atoi(arg1));
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    GRelease(serv);
	}
	if (strcmp(arg0, "list") == 0) {
	    list_volumes(serv);
	}
	if (strcmp(arg0, "sequence") == 0) {
	    int numsegs, return_mode = RETURN_SYNC;
	    char volumename[30], mask[30];
	    GSegment *segstoplay;
	    
	    if (num_args > 1 && strcmp(arg1, "return_now") == 0)
		return_mode = RETURN_NOW;
	    
	    if (!file_string) printf("Number of segments> ");
	    if (fgets(temp, 1000, fp) == NULL) exit(0);
	    numsegs = atoi(temp);
	    segstoplay = (GSegment *)malloc(numsegs * sizeof(GSegment));
	    if (segstoplay == NULL) {
		fprintf(stderr, "gman: Unable to allocate sequence structure\n");
		exit(-4);
	    }
	    for (i = 0; i < numsegs; i++) {
		if (fgets(temp, 1000, fp) == NULL) {
		    fprintf(stderr, "gman: Error reading sequence\n");
		    perror("gman: ");
		    exit(-3);
		}
		sscanf(temp, "%s %d %d %d %s", volumename, 
		       &(segstoplay[i].start),
		       &(segstoplay[i].end), &(segstoplay[i].speed), mask);
		segstoplay[i].volumenum = GWhichVolumeIndex(serv, volumename);
		if (strcmp(mask, "ALL_CHAN") == 0)
		    segstoplay[i].mask = ALL_CHAN;
		else if (strcmp(mask, "LEFT_CHAN") == 0)
		    segstoplay[i].mask = LEFT_CHAN;
		else if (strcmp(mask, "RIGHT_CHAN") == 0)
		    segstoplay[i].mask = RIGHT_CHAN;
		else if (strcmp(mask, "AUDIO_CHAN") == 0)
		    segstoplay[i].mask = AUDIO_CHAN;
		else if (strcmp(mask, "VIDEO_CHAN") == 0)
		    segstoplay[i].mask = VIDEO_CHAN;
	    }
	    ret = GPlaySequence(serv, numsegs, segstoplay, return_mode);
	    if (ret >= LOWEST_ERROR) fprintf(stderr,"Error %d = %s\n", ret, GErrorString(ret));
	    free(segstoplay);
	}
	
	if (strcmp(arg0, "help") == 0) {
	    if (DEBUG) fprintf(stderr, "Printing out local help information...");
	    printf("Commands are:\n");
	    printf("list\n");
	    printf("!!        repeats last command\n");
	    printf("search frame\n");
	    printf("switch volume-name\n");
	    printf("index [on/off]        without argument, turns on\n");
	    printf("squelch [on/off]        without argument, turns on\n");
	    printf("video [on/off]        without argument, turns on\n");
	    printf("play [speed] [start frame] [end frame]\n");
	    printf("stop\n");
	    printf("sleep [time]   default time is 1 second\n");
	    printf("echo [string]  echoes arguments.  default is nothing\n");
	    printf("quit\n");
	    printf("jog [up/forward/down/reverse/+#/-#/#]    without argument,\n");
	    printf("                                         jogs one frame\n");
	    printf("lock\n");
	    printf("unlock\n");
	    printf("alloc frames\n");
	    printf("allocat start-frame frames\n");
	    printf("free start-frame frames\n");
	    printf("record start-frame end-frame volume-name\n");
	    printf("preview volume-name\n");
	    printf("sequence [return_sync/return_now]    defaults to return_now\n");
	    printf("       Then enter a sequence, the first line of which is\n");
	    printf("     the number of segments, then a line for each segment\n");
	    printf("     in the form of: volume-name start-frame end-frame speed mask\n");
	    printf("help\n");
	}
	/*    if (file_string == NULL) printf("Return value = %d\n",ret);*/
    }
}

list_volumes(serv)
     Server *serv;
{
    int i;
    printf("Volumes available for video service:\n");
    printf("%30s     Type\n", "Volume Name");
    printf("%30s     ----\n", "------ ----");
    for (i = 0; i < GNumberVolumes(serv); i++) {
	printf("%30s     ",GVolumeName(serv,i));
	if (GVolumeType(serv, i) == RPD_DEV) {
	    if (GVolumeCapabilities(serv, i) & RECORDABLE)
		printf("record/play device\n");
	    else printf("play device\n");
	}
	else if (GVolumeType(serv, i) == INPUT_DEV) {
	    printf("uncontrolled input source\n");
	}
	else printf("unknown type of device\n");
    }
}
