#if defined(__PCM__)
#include <16f877.h>
#device ICD=TRUE
#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#endif

#include <stdlib.h>
#include <string.h>
//#include "shutter.h"


/********************************** GLOBS ***********************************/


#define TICKS_PER_SEC   244

int clock_ticks = TICKS_PER_SEC;
int seconds = 0;
int status_bit = 0;
int echo = 0;


/********************************** GLOBS ***********************************/


#INT_RTCC
clock_isr()
{
    if ( (--clock_ticks) == 0 )
    {
        ++seconds;
        //debug toggle of pin  for int_rtcc status
        status_bit = !status_bit;
        output_bit(PIN_C1, status_bit);

        clock_ticks = TICKS_PER_SEC;
    }
}

void clear_timer()
{
    set_rtcc(0);
    clock_ticks = TICKS_PER_SEC;
    seconds = 0;
}

void get_string(char* s, int max)
{
    int len;
    char c;

    max--;
    len = 0;
    do
    {
        c = getc();

        if (c == 8) // Backspace
        {
            if (len > 0)
            {
                len--;
                if (echo)
                {
                    putc(c);
                    putc(' ');
                    putc(c);
                }
            }
        }
        else if ((c >= ' ') && (c <= '~'))
        {
            if (len < max)
            {
                s[len++] = c;
                if (echo)
                    putc(c);
            }
        }
   } while(c != 13);

   s[len] = 0;

   if (echo)
       puts("\r\n");
}

void open_shutter()
{
    printf("open shutter\r\n");
    return;
}

void close_shutter()
{
    printf("close shutter\r\n");
    return;
}

int is_number(char* num_str)
{
    int is_num = 1;
    int i = 0;

    while (num_str[i] != 0)
    {
        if (!isamoung(num_str[i++],"+-0123456789"))
            is_num = 0;
    }

    return is_num;
}

void put_err(int err)
{

    //any action function should call put_err(0) upon success
    //or put_err(ERR_CODE) if there has been some sort of failure

    //if error is zero and there is no water alarm do nothing
    //if there is a water alarm and/or and error showit
    int flags;
    //have echo mode that adds LF
    flags = 0;//get_flags();
    printf("_ERR %2X%2X\r\n", flags, err);
    return;

}


byte get_io_flags()
{
    return 0;
}


void toggle_echo()
{
    echo = !echo;
    return;
}

void read_in_ports()
{
   int line_count = 0;
   
   puts("start reading ports\r\n");
   //check for halt
   while (TRUE)
   {
      if ( kbhit() )
      {
         getc();
         break;
      }
            
      printf("port b = 0x%02X    port d = 0x%02X ", input_b(), input_d());
      if ( !(++line_count%10) )
         puts(" +");
      else
         puts(" ");

      delay_ms(200);
   }

    puts("done reading ports\r\n");

    return;
}

void move_shutter(char* param)
{
    long dist;


    if ( !is_number(param))
    {
        put_err(1);
        return;
    }

    if ( strlen(param) > 5)
    {
        put_err(2);
        return;
    }

    if ( param == 0 )
    {
        put_err(3);
        return;
    }

    dist = atol(param);

    printf("move shutter %ld\r\n", dist);
    return;
}

void set_stop_pos(char* param)
{
    long pos;

    if ( !is_number(param))
    {
        put_err(1);
        return;
    }

    if ( strlen(param) > 5)
    {
        put_err(2);
        return;
    }

    if ( param == 0 )
    {
        puts("using current position\r\n");
        return;
    }

    pos = atol(param);

    printf("setting stop to %ld\r\n", pos);
    return;
}


void get_stop_pos()
{
    puts("getting stop val\r\n");
    return;
}


#define CLOSE   0
#define OPEN    1

void jog_shutter(int dir)
{

    printf("jog shutter %d\r\n", dir);
    return;
}

void show_io_flags()
{
    puts("show io flags\r\n");
    return;
}

void process_cmds()
{
    char *token;
    char string[30];
    char cmd_str[15];
    char delim[2];

    strcpy(delim, " ");

    get_string(string, 30);

    if ( string[0] == 0 )
        return;

    //grab first token
    token = strtok(string, delim);

    /******************************** OPEN **********************************/
    strcpy(cmd_str, "OPEN");

    if ( stricmp(token, cmd_str) == 0 )
    {
        open_shutter();
        return;
    }

    /******************************** CLOSE *********************************/
    strcpy(cmd_str, "CLOSE");

    if ( stricmp(token, cmd_str) == 0 )
    {
        close_shutter();
        return;
    }

    /******************************** MOVE **********************************/
    strcpy(cmd_str, "MOVE");

    if ( stricmp(token, cmd_str) == 0 )
    {
        token = strtok(0, delim);
        //takes param
        move_shutter(token);
        return;
    }

    /****************************** SET_STOP ********************************/
    strcpy(cmd_str, "SET_STOP");

    if ( stricmp(token, cmd_str) == 0 )
    {
        token = strtok(0, delim);
        //takes param
        set_stop_pos(token);
        return;
    }

    /****************************** GET_STOP ********************************/
    strcpy(cmd_str, "GET_STOP");

    if ( stricmp(token, cmd_str) == 0 )
    {
        get_stop_pos();
        return;
    }

    /******************************** JOG_O *********************************/
    strcpy(cmd_str, "JOG_O");

    if ( stricmp(token, cmd_str) == 0 )
    {
        jog_shutter(OPEN);
        return;
    }

    /******************************** JOG_C *********************************/
    strcpy(cmd_str, "JOG_C");

    if ( stricmp(token, cmd_str) == 0 )
    {
        jog_shutter(CLOSE);
        return;
    }

    /***************************** GET_FLAGS ********************************/
    strcpy(cmd_str, "GET_FLAGS");

    if ( stricmp(token, cmd_str) == 0 )
    {
        show_io_flags();
        return;
    }

    /******************************** ECHO **********************************/
    strcpy(cmd_str, "ECHO");

    if ( stricmp(token, cmd_str) == 0 )
    {
        toggle_echo();
        return;
    }
    /******************************** IN_PORTS ******************************/
    strcpy(cmd_str, "IN_PORTS");

    if ( stricmp(token, cmd_str) == 0 )
    {
        read_in_ports();
        return;
    }
    /****************************** END CMDS ********************************/

    printf("_ERR no command match\r\n");

    return;

}

main()
{

    /* initialize RTCC */
    clock_ticks = TICKS_PER_SEC;
    set_rtcc(0);
    setup_counters( RTCC_INTERNAL, RTCC_DIV_16);
    enable_interrupts(INT_RTCC);
    enable_interrupts(GLOBAL);

    /* main loop */
    while(TRUE)
    {
        process_cmds();
        puts("RDY\r\n");
    }

}
