/********************************************************
| File:         irtvdemo.c
|
| Authors:      Frank Peters, Michael Kapp
|
| Changed:      05-May-00
|
| Description:  IR remote control demo
*********************************************************/

#include "eyebot.h"
#include "irtv.h"
#include <stdio.h>

/* Nokia remote control codes */

#define CODE_0      0x6142
#define CODE_1      0x61fd
#define CODE_2      0x6102
#define CODE_3      0x60fd
#define CODE_4      0x6082
#define CODE_5      0x617d
#define CODE_6      0x6182
#define CODE_7      0x607d
#define CODE_8      0x6042
#define CODE_9      0x61bd
                               // key      => function 
#define CODE_FWD    0x6112     // "play"   => forward
#define CODE_BACK   0x606d     // "stop"   => backward
#define CODE_LEFT   0x60ed     // "rewind" => left
#define CODE_RIGHT  0x61ed     // "ffwd"   => right
#define CODE_STOP   0x61dd     // "+"      => stop
#define CODE_END    0x61a2     // "power"  => end


/* Normal speed */

#define NORMAL_V    0.03
#define NORMAL_W    0.09


/* num_code: returns the integer value for a numeric remote key (-1 for other keys) */

int num_code(int code)
{
    int i;
    const int CodeNum[10] =
        {CODE_0, CODE_1, CODE_2, CODE_3, CODE_4,
         CODE_5, CODE_6, CODE_7, CODE_8, CODE_9};

    for (i=0; i<10; i++) {
        if (code == CodeNum[i]) return i;
    }

    return -1;
}


/* num_input: wait for remote key 1..9 */

int num_input(void)
{
    int num;

    do {
        num = num_code(IRTVGet());
        if (num < 1) AUTone(500, 150);
    } while (num < 1);

    LCDPrintf("%d\n", num);

    return num;
}


/* demo loop */

void remote_control_demo(void)
 {
    int code;                                  /* current remote key */
    int fwdback = 0;                           /* current direction */
    int rightleft = 0;                         /* current turning direction */
    int mult_fb, mult_rl;                      /* speed factor (fwd/back and right/left) */
    int mult_fb_default, mult_rl_default;      /* default values for mult_xx */
    float v = 0.0, w = 0.0;
    VWHandle vw_handle;

    /* Initialize VW interface */
    vw_handle = VWInit(VW_DRIVE, 1);
    if (vw_handle == 0) {
        LCDPrintf("VWInit() error\n");
        return;
    }
    VWStartControl(vw_handle, 7, 0.3, 7, 0.1);

    /* Initialize remote control for Nokia, buffer size: 4, repetition delay: 300 */
    IRTVInit(SPACE_CODE, 15, 0, 0x3FF, SLOPPY_MODE, 4, 300);

    /* Ask for mult_xx default values */
    LCDPrintf("Enter default\n"
           "values (1..9)\n");
    LCDPutString("Mult_fb: ");
    mult_fb_default = num_input();
    LCDPutString("Mult_rl: ");
    mult_rl_default = num_input();

    mult_rl = mult_rl_default;
    mult_fb = mult_fb_default;

    LCDPrintf("Ok, ready to go!\n");

    /* Main loop */

    do {

        /* Get remote key from buffer */
        code = IRTVRead();

        switch (code) {

            /* Go forward */
            case CODE_FWD:
                mult_fb++;                       /* increase speed factor */
                mult_rl = mult_rl_default;
                if (fwdback == 2)                /* direction change => reset speed to default */
                {
                    mult_fb = mult_fb_default;
                }

                fwdback = 1;
                rightleft = 0;
                LCDPrintf(" Forward (%d)\n", mult_fb);
                break;

            /* Go backward */
            case CODE_BACK:
                mult_fb++;
                mult_rl = mult_rl_default;
                if (fwdback == 1)
                {
                    mult_fb = mult_fb_default;
                }
                fwdback = 2;
                rightleft = 0;
                LCDPrintf(" Back (%d)\n", mult_fb);
                break;

            /* Turn left */
            case CODE_LEFT:
                mult_rl++;
                if (rightleft == 1)
                {
                    mult_rl = mult_rl_default;
                }
                rightleft = 2;
                LCDPrintf(" Left (%d)\n", mult_rl);
                break;

            /* Turn right */
            case CODE_RIGHT:
                mult_rl++;
                if (rightleft == 2)
                {
                    mult_rl = mult_rl_default;
                }
                rightleft = 1;
                LCDPrintf(" Right (%d)\n", mult_rl);
                break;

            /* Stop! */
            case CODE_STOP:
            case CODE_0:
                fwdback = 0;
                rightleft = 0;
                mult_rl = mult_rl_default;
                mult_fb = mult_fb_default;
                LCDPrintf(" Stop\n");
                break;
        }

        /* calculate current VW parameters */
        switch (rightleft) {
            case 0:
                w = 0.0;
                break;
            case 1:
                w = -1.0 * NORMAL_W * mult_rl;
                break;
            case 2:
                w = NORMAL_W * mult_rl;
                break;
        }

        switch (fwdback) {
            case 0:
                v = 0.0;
                break;
            case 1:
                v = NORMAL_V * mult_fb;
                break;
            case 2:
                v = -NORMAL_V * mult_fb;
                w = -w;
                break;
        }

        VWSetSpeed(vw_handle, v, w);

        /* Loop until one of the "end" keys is pressed */
    } while (code!=CODE_END && KEYRead()==0);

    /* Turn off motors and release resources */
    VWSetSpeed(vw_handle, 0.0, 0.0);
    LCDPrintf(" End\n");

    IRTVTerm();
    VWRelease(vw_handle);
}


/* main function */

int main()
{
    LCDMode(SCROLLING | NOCURSOR);
    LCDClear();
    LCDPutString("*Remote Control\n"
           "*Demo\n"
           "*by Frank Peters"
           "*   Michael Kapp");
    LCDMenu("", "", "", "END");

    remote_control_demo();

    return 0;
}
