#ifndef _APP_SERV_H_
#define _APP_SERV_H_

#include "app_cfg.h"
#include "control.h"
#include <cpu.h>

#define APP_DEBUG    0

#define CONSOLE_TCP_DEFAULT_PORT    10000

#define RELAY_COUNT         3

#if defined(BOARD_SOLARIUM_VLAD)
typedef struct 
{
    CPU_INT08U user_menu;
        /// 
        #define USER_MENU_IDLE                     0
        /// 
        #define USER_MENU_WARNING_1                1
        /// 
        #define USER_MENU_WARNING_2                2
        /// 
        #define USER_MENU_SELECT_CH                3
        /// 
        #define USER_MENU_SELECT_MODE              4
        /// 
        #define USER_MENU_ACK_MODE                 5
        /// 
        #define USER_MENU_SELECT_PAY_TYPE          6
        /// 
        #define USER_MENU_CASH_PAYING              7
        /// 
        #define USER_MENU_CARD_PAYING              8
        /// 
        #define USER_MENU_CARD_PROCESSING          9
        /// 
        #define USER_MENU_CARD_FAIL                10
        /// 
        #define USER_MENU_CARD_OK                  11
        /// 
        #define USER_MENU_SHOW_THANKS              12
        /// 
        #define USER_MENU_SERVICE_PASS             13
        /// 
        #define USER_MENU_SELECT_CH_CLEANING       14
        #define USER_MENU_SELECT_CH_SERVICE        15
        #define USER_MENU_SELECT_CH_TESTMODE       16
        /// 
        #define USER_MENU_SKIN_ATTENTION_1         17
        /// 
        #define USER_MENU_SKIN_ATTENTION_2         18
        /// 
        #define USER_MENU_SKIN_ATTENTION_3         19
        /// 
        #define USER_MENU_SKIN_ATTENTION_4         20
        /// 
        #define USER_MENU_SELECT_SERVICE_TIME      21

        // меню для карточной системы
        #define USER_MENU_WAIT_CARD                     30
        #define USER_MENU_BALANCE_CARD                  31
        #define USER_MENU_START_INSERT_CARD_MONEY       32
        #define USER_MENU_ALL_PRICE                     33
        #define USER_MENU_SILVER_BONUS                  34
        #define USER_MENU_GOLD_BONUS                    35
        #define USER_MENU_PLATINUM_BONUS                36
        #define USER_MENU_BRILLANCE_BONUS               37
        #define USER_MENU_START_PAY_CARD                38
        #define USER_MENU_INSERT_BANK_CARD              39
        #define USER_MENU_ERROR_BANK_CARD               40
        #define USER_MENU_INSERT_BONUS_CARD             41
        #define USER_MENU_FINISH_PAY_BONUS_CARD         42

        #define USER_MENU_ABONENT_PROCESSING            43
        #define USER_MENU_ABONENT_WRONG                 44

        #define USER_MENU_ABONEMENT_FAIL                45

        /// 
        #define USER_MENU_ERROR                    255

    CPU_INT08U user_menu_prev;

    CPU_INT08U menu_timeout;
        #define MENU_THANKS_TIMEOUT         5
        #define MENU_CARD_FAIL_TIMEOUT      3
        #define MENU_CARD_ABONEMENT_FAIL_TIMEOUT      6
        #define MENU_ATTENTION_TIMEOUT      5

    CPU_INT08U ch_index;
    CPU_INT08U mode_index;
    CPU_INT08U pay_index;
        #define PAY_TYPE_CARD_ABONEMENT         0
        #define PAY_TYPE_CARD                   1
        #define PAY_TYPE_CASH                   2

    CPU_INT08U solar_state[CHANNELS_NUM];
        #define SOLAR_STATE_FREE                0
        #define SOLAR_STATE_TIMEOUT_PRE         1
        #define SOLAR_STATE_SUNBURN             2
        #define SOLAR_STATE_VENT                3
        #define SOLAR_STATE_TIMEOUT_AFTER       4
        #define SOLAR_STATE_PAUSE               5
        #define SOLAR_STATE_CLEANING            6

    CPU_INT08U sunburn_mode[CHANNELS_NUM];
        #define SUNBURN_MODE_COLLATEN       0
        #define SUNBURN_MODE_UF             1
        #define SUNBURN_MODE_MAX            2

    CPU_INT08U pause_timeout[CHANNELS_NUM];
        #define SOLAR_PAUSE_TIMEOUT 60
    
    CPU_INT08U skin_flags;
    CPU_INT16U blink_ctr;

    CPU_INT32U timetoend[CHANNELS_NUM];
    CPU_INT32U relay_timeout[CHANNELS_NUM];
    CPU_INT32U timetopay;
    CPU_INT32U moneytopay;
    CPU_INT32U last_key_time;
        #define MENU_KEY_PRESS_TIMEOUT_MS   300000

    CPU_INT32U time_cleaning_start[CHANNELS_NUM];
       
    CPU_INT08U solar_srv[CHANNELS_NUM];
        #define SOLAR_IN_SERVICE    1
        #define SOLAR_IN_TEST       2

    CPU_INT32U last_card_manipulation_time;
        #define MENU_CARD_MANIPULATION_TIMEOUT_MS   10000
        #define MENU_CARD_WRONG_TIMEOUT_MS          3000
        #define MENU_WAIT_CARD_ABONEMENT_TIMEOUT_MS          20000

    CPU_INT08U current_abonement;
        #define SILVER_ABONEMENT        0
        #define GOLD_ABONEMENT          1
        #define PLATINUM_ABONEMENT      2
        #define DIAMOND_ABONEMENT       3

    CPU_INT32U abonementtopay;

} ApplicationState;
extern ApplicationState app_state;
#endif

#if defined(BOARD_SOLARIUM_WEB)
typedef struct 
{
    CPU_INT08U state;
        /// свободно 
        #define APP_STATE_IDLE              0
        /// запрос желаемого времени у пользователя
        #define APP_STATE_USER_INPUT        1
        /// ожидание подтверждения времени
        #define APP_STATE_WAITING_ACK       2
        /// пауза перед сеансом
        #define APP_STATE_PRE_PAUSE         3
        /// загар 
        #define APP_STATE_SUNBURN           4
        /// вентиляция
        #define APP_STATE_VENTILATION       5
    CPU_INT32S timetoend;
    CPU_INT32U userinputtime;
    CPU_INT32U userinputmoney;

    CPU_INT32S user_id;
    CPU_INT32S timefromserver;
    CPU_INT32S moneyfromserver;

} ApplicationState;
extern ApplicationState app_state;

#define SOLARIUM_LAMPS_ON()     {FIO0SET_bit.P0_24 = 1;}
#define SOLARIUM_LAMPS_OFF()    {FIO0CLR_bit.P0_24 = 1;}
#define SOLARIUM_VENT_ON()      {FIO0SET_bit.P0_23 = 1;}
#define SOLARIUM_VENT_OFF()     {FIO0CLR_bit.P0_23 = 1;}
#define SOLARIUM_ZUMMER_ON()    {FIO1SET_bit.P1_21 = 1;}
#define SOLARIUM_ZUMMER_OFF()   {FIO1CLR_bit.P1_21 = 1;}

/// таймаут связи с сервером, если сервер долго не запрашивал статус, отображаем, что связи нет
#define HTTP_SERVER_CONN_OK_TIMEOUT 5

extern const char* AppStatusStr(CPU_INT08U state);
extern void ZummerBeep(void);
extern void ZummerLongBeep(void);

#endif

extern CPU_INT32U incas_bill_nom_counter[24];
extern CPU_INT32U incas_common_bill_counter;

#define   KBRD_TASK_STK_SIZE        64
#define   USER_TASK_STK_SIZE        320
#define   MENU_TASK_STK_SIZE        256
#define   COIN_TASK_STK_SIZE        64
#define   VALIDATOR_TASK_STK_SIZE   192
#define   FISCAL_TASK_STK_SIZE      192
#define   MODEM_TASK_STK_SIZE       256
#define   CONSOLE_TASK_STK_SIZE     320
#define   HOST_TASK_STK_SIZE        256
#define   TERM_TASK_STK_SIZE        512
#define   HTTPD_TASK_STK_SIZE       512
#define   SCORE_TASK_STK_SIZE       128
#define   MUSIC_TASK_STK_SIZE       256

#define   VALIDATOR_TASK_PRIO   (USER_HIGHEST_PRIO)
#define   USER_TASK_PRIO        (USER_HIGHEST_PRIO + 1)
#define   COIN_TASK_PRIO        (USER_HIGHEST_PRIO + 2)
#define   KBRD_TASK_PRIO        (USER_HIGHEST_PRIO + 3)
#define   FISCAL_TASK_PRIO      (USER_HIGHEST_PRIO + 4)
#define   MENU_TASK_PRIO        (USER_HIGHEST_PRIO + 5)
#define   CONSOLE_TASK_PRIO     (USER_HIGHEST_PRIO + 6)
#define   HOST_TASK_PRIO        (USER_HIGHEST_PRIO + 7)
#define   HTTPD_TASK_PRIO       (USER_HIGHEST_PRIO + 8)
#define   TERM_TASK_PRIO        (USER_HIGHEST_PRIO + 9)
#define   SCORE_TASK_PRIO       (USER_HIGHEST_PRIO + 10)
#define   MUSIC_TASK_PRIO       (USER_HIGHEST_PRIO + 11)
#define   MODEM_TASK_PRIO       (USER_LOWEST_PRIO)


enum{
  EVENT_SEC = 1,
  EVENT_STARTUP,
  
  EVENT_COIN_INSERTED,
  EVENT_BILL_ESCROW,
  EVENT_BILL_STACKED,
  
  EVENT_MODE_CHANGE,
  
  EVENT_KEY_EMPTY,
  EVENT_KEY_POST1,
  EVENT_KEY_POST2,
  EVENT_KEY_POST3,
  EVENT_KEY_POST4,
  EVENT_KEY_POST5,
  EVENT_KEY_POST6,
  EVENT_KEY_POST7,
  EVENT_KEY_POST8,
  EVENT_KEY_CANSEL,
  EVENT_KEY_START,
  EVENT_KEY_LEFT,
  EVENT_KEY_RIGHT,
  EVENT_KEY_DOWN,
  EVENT_KEY_UP,
  EVENT_KEY_STOP,
#if defined(BOARD_SOLARIUM_WEB)
  EVENT_KEY_DIGIT0,
  EVENT_KEY_DIGIT1,
  EVENT_KEY_DIGIT2,
  EVENT_KEY_DIGIT3,
  EVENT_KEY_DIGIT4,
  EVENT_KEY_DIGIT5,
  EVENT_KEY_DIGIT6,
  EVENT_KEY_DIGIT7,
  EVENT_KEY_DIGIT8,
  EVENT_KEY_DIGIT9,
  EVENT_KEY_STAR,
  EVENT_KEY_SHARP,
  EVENT_REQUEST_USER_INPUT,
  EVENT_USER_INPUT_FINISHED,
  EVENT_SHOW_ZERO_MONEY,
  EVENT_NACK_USER_INPUT,
  EVENT_ACK_USER_INPUT,
  EVENT_ABORT_OPERATIONS,
  EVENT_SYSTEM_REBOOT,
#endif

#if defined(BOARD_SOLARIUM_VLAD)
  EVENT_KEY_F1,
  EVENT_KEY_F2,
  EVENT_KEY_F3,
  EVENT_KEY_SOLAR_START1,
  EVENT_KEY_SOLAR_START2,
  EVENT_KEY_SOLAR_START3,//28
  EVENT_KEY_SOLAR_STOP1,
  EVENT_KEY_SOLAR_STOP2,
  EVENT_KEY_SOLAR_STOP3,
  EVENT_OPEN_RELAY1,
  EVENT_OPEN_RELAY2,
  EVENT_OPEN_RELAY3,
  EVENT_CLOSE_RELAY1,
  EVENT_CLOSE_RELAY2,
  EVENT_CLOSE_RELAY3,
  EVENT_BLINK,
  EVENT_FINISH_PAYMENT,
  EVENT_PASS_OK,
  EVENT_PASS_FAIL,
  EVENT_PLAY_SOUND_FILE,
  EVENT_STOP_SOUND_FILE,
  EVENT_UPDATE_MUSIC_VOLUME,
#endif

  EVENT_INCASSATION,
  EVENT_INCASSATION_FINISH,
  #if defined(BOARD_POST_CARWASH)
  EVENT_PULSEOUT
  #elif defined(BOARD_CENTRAL_CARWASH)
  EVENT_REREAD_SIGNAL_LEVEL,
  #endif

  #if defined(BOARD_SOLARIUM_VLAD)
  EVENT_FINISH_PAYMENT_ABONEMENT,
  EVENT_FINISH_PAYMENT_ABONEMENT_SOLARIUM,
  #endif
};

#define EVENT_KEY_LEFT EVENT_KEY_POST2
#define EVENT_KEY_RIGHT EVENT_KEY_POST5

extern CPU_INT32U SystemTime;
extern CPU_INT32U TerminalMoney;
extern CPU_INT08U RecentChannel;

extern void StartUserApplication(void);
extern void UserStartupFunc(void);
extern void PostUserEvent(int event);
extern void InitUserMenu(void);
extern int GetRecentChannelPrice(CPU_INT08U ch, CPU_INT32U* price, CPU_INT32U* time);
extern void save_config_params(void);
extern void init_config_params(void);
extern void AddOutPulses(int count, int len_ms, int len_pause_ms);
extern void UserPrintErrorMenu(void);
extern CPU_INT32U GetAcceptedMoney(void);
extern void SetAcceptedMoney(CPU_INT32U money);
extern void PrintCardBill(void);
extern void UserPrintTerminalRequestMenu();
extern void UserPrintPaymentErrorMenu(void);
extern void UserPrintAbonementPaymentErrorMenu(void);
extern void UserPrintResultMenu(void);

#endif //#ifndef _APP_SERV_H_
