/********************************************************************
 * FUNCTION do_exit (local RPC)
 * 
 * exit
 *
 * Exit the configuration mode
 *
 * INPUTS:
 * server_cb == server control block to use
 *    rpc == RPC method for the show command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    do_exit (server_cb_t *server_cb,
             obj_template_t *rpc,
             const xmlChar *line,
             uint32  len)
{
    status_t res = NO_ERR;
    val_value_t *valset = get_valset(server_cb, rpc, &line[len], &res);

    if (valset && res == NO_ERR) {

        ;
    }

    if (res == NO_ERR || res == ERR_NCX_SKIPPED) {
        session_cb_t *session_cb = server_cb->cur_session_cb;
        if (!session_cb->config_mode) {
            log_error("\nError: configure mode is not active\n");
            res = ERR_NCX_OPERATION_FAILED;
        } else {
            exit_config_mode(session_cb);
        }
    }

    if (valset) {
        val_free_value(valset);
    }

    return res;

}  /* do_exit */
/********************************************************************
 * FUNCTION force_exit_config_mode
 * (session was dropped -- exit config mode)
 * 
 * INPUTS:
 *    session_cb == session control block to use
 *********************************************************************/
void
    force_exit_config_mode (session_cb_t *session_cb)
{
    const xmlChar *nam = NCX_EL_DEFAULT;
    if (session_cb->session_cfg)  {
        nam = session_cb->session_cfg->name;
    }
    log_info("\nForced exit from configure mode for session '%s'\n", nam);
    exit_config_mode(session_cb);

} /* force_exit_config_mode */
/********************************************************************
 * FUNCTION process_exit
 * (config mode input received)
 *  Handle the exit command based on the current mode
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    session_cb == session control block to use
 * RETURNS:
 *   status
 *********************************************************************/
static status_t
    process_exit (server_cb_t *server_cb,
                  session_cb_t *session_cb)
{
    /*** TBD: add warning about edits pending ***/

    status_t res = NO_ERR;

    /* exit to previous level or root or out of config mode */
    if (session_cb->config_curobj) {
        /* check if edits are applied when the mode is exited */
        if (session_cb->config_edit_mode == CFG_EDITMODE_LEVEL) {
            if (session_cb->config_etree) {
                /* there may be an edit to apply */
                if (!session_cb->config_edit_dirty ||
                    dlq_count(&session_cb->config_editQ) == 0) {
                    
                    /* entered mode and then exited without adding any
                     * edits so try adding the container or list    */
                    res = add_edit(session_cb);
                }
                //clear_one_level(session_cb);
            }
            if (res == NO_ERR) {
                res = process_apply(server_cb, session_cb);
            }
        }

        /* get parent of current object */
        session_cb->config_curobj = 
            obj_get_real_parent(session_cb->config_curobj);

        if (!session_cb->config_curobj || 
            obj_is_root(session_cb->config_curobj)) {

            /* exit to root-level, stay in config mode */
            session_cb->config_curobj = NULL;
            session_cb->config_ecurval = NULL;
            val_free_value(session_cb->config_etree);
            session_cb->config_etree = NULL;
        } else if (session_cb->config_ecurval) {
            clear_one_level(session_cb);
        }
    } else {
        /* no current object so exit config mode */
        exit_config_mode(session_cb);
    }

    return res;

}  /* process_exit */
void action_keyevent(keyevent_t event)
{
    uint8_t key = event.key.col;
    if (config_mode) {
        /* config mode */
        switch (key) {
            case KEY_K1:
                if (event.pressed) {
                    switch_layout();
                }
                break;
            case KEY_K2:
                if (event.pressed) {
                    switch_backlight();
                }
                break;
            case KEY_CFG:
                if (event.pressed) {
                    exit_config_mode();
                }
                break;
        }
    }
    else {
        /* normal mode */
        switch (key) {
            case KEY_K1: case KEY_K2:
                if (event.pressed) {
                    /* press */
                    switch (backlight_mode) {
                        case 0: case 6:
                            softpwm_led_on(key);
                            break;
                        case 1: case 2:
                            softpwm_led_increase(LED_KEY_SIDE - 1 + backlight_mode, 32);
                        case 3 ... 5:
                            softpwm_led_set(key, backlight_brightness_high);
                            break;
                    }
                }
                else {
                    /* release */
                    switch (backlight_mode) {
                        case 0: case 6:
                            softpwm_led_off(key);
                            break;
                        case 1 ... 5:
                            softpwm_led_set(key, 0);
                            break;
                    }
                }
                break;
            case KEY_TT:
                if (event.pressed) {
                    vibration(32);
                    switch (backlight_mode) {
                        case 1: case 2:
                            softpwm_led_increase(LED_KEY_SIDE - 1 + backlight_mode, 32);
                            break;
                    }
                }
                break;
            case KEY_TP:
                switch (backlight_mode) {
                    case 1: case 5:
                        if (event.pressed) {
                            softpwm_led_set(LED_BOARD_SIDE, backlight_brightness_high);
                        }
                        else {
                            softpwm_led_set(LED_BOARD_SIDE, backlight_brightness_mid);
                        }
                        break;
                    case 2: case 4:
                        if (event.pressed) {
                            softpwm_led_set(LED_KEY_SIDE, backlight_brightness_high);
                        }
                        else {
                            softpwm_led_set(LED_KEY_SIDE, backlight_brightness_mid);
                        }
                        break;
                }
                break;
            case KEY_CFG:
                if (event.pressed) {
                    enter_config_mode();
                }
                break;
        }
    }