/*
 *  Copyright (C) by Y.Ishioka 2012-2013
 */
#include <WScom.h>
#include <WSCfunctionList.h>
#include <WSCbase.h>

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <time.h>

#include <sys/stat.h>
#include <sys/types.h>

#include <demo_main.h>


//	シリアル通信オブジェクト
#include "SIserialComm.h"
CSIserialComm    SIserialComm;

#define  COM_TX_BUFFER_SZ   0x0080
#define  COM_RX_BUFFER_SZ   0x0400
#define  COM_DT_BUFFER_SZ   0x8000
#define  COM_JPG_BUFFER_SZ  0x4000


unsigned char  com_tx_buffer[COM_TX_BUFFER_SZ] ;
unsigned char  com_rx_buffer[COM_RX_BUFFER_SZ] ;
unsigned char  demo_buffer[ COM_DT_BUFFER_SZ ] ;
unsigned char  demo_jpg_buffer[ COM_JPG_BUFFER_SZ ] ;

void  demo_com_close( void ) ;
void  demo_draw_set_file( char *name, char *date ) ;
void  demo_draw_init( void ) ;

int  demo_reset_flag ;

int  demo_data_mode ;
int  demo_data_len ;
int  demo_data_readlen ;
int  demo_time_count ;
int  demo_buffer_use ;
int  demo_buffer_rp ;
int  demo_buffer_wp ;


/*
 *
 */
void  demo_recv_serial( void )
{
    int  rx_len, len ;
    int  loop ;
    unsigned char  *src, *dst ;

    if( SIserialComm.checkRecvQueue() <= 0 ) {
        return ;
    }

    src = com_rx_buffer ;
    rx_len = SIserialComm.recv( src, COM_RX_BUFFER_SZ ) ;
    if( rx_len < (COM_DT_BUFFER_SZ - demo_buffer_wp) ) {
        dst = &demo_buffer[demo_buffer_wp] ;
        for( loop=0 ; loop<rx_len ; loop++ ) {
            *dst++ = *src++ ;
        }
        demo_buffer_use += rx_len ;
        demo_buffer_wp += rx_len ;
        if( demo_buffer_wp >= COM_DT_BUFFER_SZ ) {
            demo_buffer_wp = 0 ;
        }
    } else {
        len = COM_DT_BUFFER_SZ - demo_buffer_wp ;
        dst = &demo_buffer[demo_buffer_wp] ;
        for( loop=0 ; loop<len ; loop++ ) {
            *dst++ = *src++ ;
        }
        demo_buffer_wp = 0 ;
        len = rx_len - len ;
        dst = &demo_buffer[0] ;
        for( loop=0 ; loop<len ; loop++ ) {
            *dst++ = *src++ ;
        }
        demo_buffer_use += rx_len ;
        demo_buffer_wp = len ;
    }
}


/*
 *
 */
unsigned char  demo_data_get_1char( void )
{
    unsigned char  data ;

    data = demo_buffer[ demo_buffer_rp++ ] ;
    if( demo_buffer_rp >= COM_DT_BUFFER_SZ ) {
        demo_buffer_rp = 0 ;
    }
    demo_buffer_use-- ;

    return( data ) ;
}


/*
 *
 */
void  demo_save_data( void )
{
    struct tm   *now_tm ;
    time_t  now ;
    FILE  *wp ;
    char  name[128] ;
    char  date[32] ;

    now = time( NULL ) ;
    now_tm = localtime( &now ) ;

    sprintf( name, "%04d%02d%02d\\.",
             now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday ) ;
    wp = fopen( name, "r" ) ;
    if( wp == NULL ) {
        mkdir( name ) ;
    } else {
        fclose( wp ) ;
    }

    sprintf( name, "Completed [%04d/%02d/%02d %02d:%02d:%02d]",
             now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday,
             now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec ) ;
    demvlab_000->setProperty( WSNlabelString, name ) ;
    sprintf( name, "%04d%02d%02d\\%04d%02d%02d_%02d%02d%02d.jpg",
             now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday,
             now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday,
             now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec ) ;

    wp = fopen( name, "wb" ) ;
    fwrite( demo_jpg_buffer, 1, demo_data_len, wp ) ;
    fclose( wp ) ;

    sprintf( date, "%04d/%02d/%02d\n%02d:%02d:%02d",
             now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday,
             now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec ) ;
    demo_draw_set_file( name, date ) ;

#if 0
    /* delete graphics file */
    remove( name ) ;
#endif
}


void  demo_data_init( void )
{
    demo_data_mode = 0 ;
    demo_data_len = 0 ;
    demo_time_count = 0 ;
    demo_buffer_use = 0 ;
    demo_buffer_rp = 0 ;
    demo_buffer_wp = 0 ;
}


/*
 *    require timer=20msec
 */
void  demo_data_analize( void )
{
    unsigned char  data ;
    unsigned char  *dst ;
    int  len ;
    int  loop ;
    char  buff[64] ;

    if( demo_buffer_use <= 0 ) {
        if( demo_data_mode > 0 ) {
            if( demo_time_count++ > 50 ) {
                /* time out ( 20msec*100=2sec ) */
#if 1
                if( demo_data_mode >= 4 ) {
                    demo_save_data() ;
                }
#endif
                demo_data_mode = 0 ;
                demo_time_count = 0 ;
                demvlab_000->setProperty( WSNlabelString, "Receive timeout." ) ;
            }
        }
        return ;
    }
    demo_time_count = 0 ;

    while( 1 ) {
        if( demo_reset_flag != 0 ) {
            demo_reset_flag = 0 ;
            return ;
        }

        if( demo_buffer_use <= 0 ) {
            /* buffer data noting */
            return ;
        }

        switch( demo_data_mode ) {
        case  0:
            data = demo_data_get_1char() ;
            if( data == 'Y' ) {
                demo_data_mode++ ;
            }
            break ;

        case  1:
            data = demo_data_get_1char() ;
            if( data == 'I' ) {
                demo_data_len = 0 ;
                demo_data_mode++ ;
            } else {
                /* format not match */
                demo_data_mode = 0 ;
                demvlab_000->setProperty( WSNlabelString, "Receive data error(1)." ) ;
            }
            break ;

        case  2:
            data = demo_data_get_1char() ;
            demo_data_len += (int)(data<<8) & 0x0000ff00 ;
            demo_data_mode++ ;
            break ;

        case  3:
            data = demo_data_get_1char() ;
            demo_data_len += (int)data & 0x000000ff ;

            sprintf( buff, "data size = %d", demo_data_len ) ;
            demvlab_000->setProperty( WSNlabelString, buff ) ;

            demo_data_readlen = 0 ;
            demo_data_mode++ ;
            break ;

        case  4:
            len = demo_data_len - demo_data_readlen ;
            dst = &demo_jpg_buffer[demo_data_readlen] ;
            if( len < demo_buffer_use ) {
                for( loop=0 ; loop<len ; loop++ ) {
                    *dst++ = demo_data_get_1char() ;
                }
                demo_data_readlen += len ;
                demo_data_mode++ ;
            } else {
                len = demo_buffer_use ;
                for( loop=0 ; loop<len ; loop++ ) {
                    *dst++ = demo_data_get_1char() ;
                }
                demo_data_readlen += len ;
                if( demo_data_readlen == demo_data_len ) {
                    demo_data_mode++ ;
                }
            }
#if 1
            sprintf( buff, "readlen = %d Byte / %d Byte", demo_data_readlen, demo_data_len ) ;
            demvlab_000->setProperty( WSNlabelString, buff ) ;
#endif
            break ;

        case  5:
            data = demo_data_get_1char() ;
            if( data == 'S' ) {
                demo_data_mode++ ;
            } else {
                /* format not match */
                demo_data_mode = 0 ;
                demvlab_000->setProperty( WSNlabelString, "Receive data error(5)." ) ;
            }
            break ;

        case  6:
            data = demo_data_get_1char() ;
            if( data == 't' ) {
                demo_data_mode++ ;
            } else {
                /* format not match */
                demo_data_mode = 0 ;
                demvlab_000->setProperty( WSNlabelString, "Receive data error(6)." ) ;
            }
            break ;

        case  7:
            data = demo_data_get_1char() ;
            if( data == 'u' ) {
                demo_data_mode++ ;
            } else {
                /* format not match */
                demo_data_mode = 0 ;
                demvlab_000->setProperty( WSNlabelString, "Receive data error(7)." ) ;
            }
            break ;

        case  8:
            data = demo_data_get_1char() ;
            if( data == 'd' ) {
                demo_data_mode++ ;
            } else {
                /* format not match */
                demo_data_mode = 0 ;
                demvlab_000->setProperty( WSNlabelString, "Receive data error(8)." ) ;
            }
            break ;

        case  9:
            data = demo_data_get_1char() ;
            if( data == 'i' ) {
                demo_data_mode++ ;
            } else {
                /* format not match */
                demo_data_mode = 0 ;
                demvlab_000->setProperty( WSNlabelString, "Receive data error(9)." ) ;
            }
            break ;

        case 10:
            data = demo_data_get_1char() ;
            if( data == 'o' ) {
                demo_save_data() ;
                demo_data_mode = 0 ;
            } else {
                /* format not match */
                demo_data_mode = 0 ;
                demvlab_000->setProperty( WSNlabelString, "Receive data error(10)." ) ;
            }
            break ;
        }
    }
}


/*
 *
 */
void  demo_com_reset( WSCbase*  base)
{
    demo_reset_flag = 1 ;
    SIserialComm.clearRecvQueue() ;
    demvlab_000->setProperty( WSNlabelString, "" ) ;
    demo_data_init() ;
    demo_draw_init() ;

    demo_main->setAbsoluteDraw(True);
    demo_main->draw();
    demo_main->redraw();
}

char  demo_com_open_port[16] ;


/*
 *
 */
void  demo_com_open( WSCbase*  base)
{
    WSCoption  *objport = demopti_003 ;
    WSCoption  *objbaud = demopti_005 ;
    long  port, baud ;
    int  ret ;
    char  portname[10] ;
    char  buff[64] ;

    port = objport->getValue() ;
    baud = objbaud->getValue() ;
    sprintf( portname, "COM%d", port ) ;

    sprintf( buff, "%s %d", (char *)portname, baud ) ;
    demvlab_000->setProperty( WSNlabelString, buff ) ;

    demo_com_close() ;

    ret = SIserialComm.open( portname, baud ) ;
    if( ret != 1 ) {
        sprintf( buff, "%s OPEN ERROR", portname ) ;
        demvlab_000->setProperty( WSNlabelString, buff ) ;
    } else {
        SIserialComm.clearRecvQueue() ;
        strcpy( demo_com_open_port, portname ) ;
    }
}


/*
 *
 */
void  demo_com_close( void )
{
    WSCstring  tmp ;
    int  ret ;
    char  buff[64] ;

    if( demo_com_open_port[0] == 0x00 ) {
        return ;
    }

    SIserialComm.clearRecvQueue() ;
    ret = SIserialComm.close() ;
    if( ret != 1 ) {
        sprintf( buff, "%s CLOSE ERROR", demo_com_open_port ) ;
        demvlab_000->setProperty( WSNlabelString, buff ) ;
    } else {
        demo_com_open_port[0] = 0x00 ;
    }
}


/*
 *
 */
void  demo_com_init( WSCbase* object )
{
    demo_data_init() ;

    demo_reset_flag = 0 ;
    demo_com_open_port[0] = 0x00 ;
    demo_com_open( object) ;

}

