// main.cpp - main for sketch program.
// Written by (c) Wayne Pollock, 2000.  All Rights Reserved.

#include <iostream>
#include <sstream>  // Older compilers require <strstream> or <strstrea>.
#include <ctype>
#include <cstring>
#include "screen.h"

using namespace std;

void parse_circle_cmd ( istringstream& cmd );
void parse_line_cmd ( istringstream& cmd );
void display_help ();
void pause ();  // Wait for user to hit Enter.

Screen scrn;	// This project uses only one screen object.

int main ()
{
    char buf[256], cmd[256];
    scrn.clear( '.' );  // start with empty screen.

    for ( ;; )
    {	try
	{   scrn.display();
	    cerr << "\n\tEnter a command ('help' for brief help): " << flush;
	    if ( !cin.getline( buf, sizeof (buf) ) )
		break;
	    istringstream ibuf( buf );
	    if ( !(ibuf >> cmd) )
		continue;	//A blank line is skipped.

	    for ( unsigned int i=0; i < strlen(cmd); ++i ) // Capitalize command
		cmd[i] = (char) toupper( cmd[i] );

	    if ( strcoll( cmd, "CLEAR" ) == 0 ) {
		scrn.clear( '.' );
	    } else if ( strcoll( cmd, "EXIT" ) == 0 ) {
		return 0;
	    } else if ( strcoll( cmd, "HELP" ) == 0 || strcoll( cmd, "?" ) == 0 ) {
		display_help();
	    } else if ( strcoll( cmd, "LINE" ) == 0 ) {
		parse_line_cmd( ibuf );
	    } else if ( strcoll( cmd, "CIRCLE" ) == 0 ) {
		parse_circle_cmd( ibuf );
	    } else {
		char err[256] = "Unrecognized command: ";
		strcat( err, cmd );
		throw err;
	    }
	}
	catch ( char* msg )
	{   cerr << "*** Error: " << msg << "!\a" << endl;
	    pause();
	}
    } // end for

    return 0;	// If we get to here, an EOF was encountered!
}


// This code allows either two or four values:
void parse_line_cmd ( istringstream& cmd )
{
    int start_row, start_col, end_row, end_col;
    Point start_pt, end_pt;
    char junk[256];

    if ( !(cmd >> start_row) ) {
	throw "Bad first argument to Line";
    } else if ( !(cmd >> start_col) ) {
	throw "Bad second argument to Line";
    } else if ( !(cmd >> end_row) ) {	// Assume a relative line!
	end_pt = scrn.cur_pt() + Point( start_row, start_col );
	start_pt = scrn.cur_pt();
    } else if ( !(cmd >> end_col) ) {
	throw "Bad fourth argument to Line";
    } else if ( cmd >> junk ) {
	throw "Extra arguments to Line";
    } else {
	start_pt = Point( start_row, start_col );
	end_pt = Point( end_row, end_col );
    }
    scrn.draw_line( start_pt, end_pt );
    return;
}


// This code is tricky, since you can supply radius only, or row, col, radius:
void parse_circle_cmd ( istringstream& cmd )
{
    int arg1, arg2, arg3, radius;
    char junk[256];
    Point center;

    if ( !(cmd >> arg1) ) {
	throw "Bad first argument to Circle";
    } else if ( !(cmd >> arg2) ) {
	if ( cmd >> junk )
	    throw "Bad second argument to Circle";
	center = scrn.cur_pt();  // Else assume a relative circle.
	radius = arg1;
    } else if ( !(cmd >> arg3) ) {
	throw "Bad third argument to Circle";
    } else if ( cmd >> junk ) {
	throw "Extra arguments to Circle";
    } else {
	center = Point( arg1, arg2 );
	radius = arg3;
    }
    if ( radius <= 0 )
	throw "The circle's radius must be greater than zero";
   scrn.draw_circle( center, radius );
   return;
}


void display_help ()
{
    cerr  << "\n\n\n\n\n\nSummary of Legal Commands:\n" << endl;
    cerr  << "\tClear  -  erase the screen.\n" << endl;
    cerr  << "\tCircle <center_row> <center_col> <radius>\n"
	  << "\tCircle <radius>  - draws a circle centered on "
	     "the \"current point\".\n" << endl;
    cerr  << "\tExit   -  quit the program.\n" << endl;
    cerr  << "\tHelp (or \"?\") - display this message.\n" << endl;
    cerr  << "\tLine <start_row> <start_col> <end_row> <end_col>\n"
	  << "\tLine <row> <col>  - draws a line from "
	     "the \"current point\" to here.\n" << endl;
    cerr  << "\n\n\n\n" << endl;
    pause();
}


void pause ()
{
    char line[256];
    cerr << "\nHit Enter to continue..." << flush;
    if ( !cin.getline( line, sizeof( line ) ) )
	cin.clear();  // reset the EOF bit.
    return;
}
