/*
 * $RCSfile: timers.h,v $  $Revision: 1.8 $  $Name:  $
 * $Id: timers.h,v 1.8 2006/10/04 05:21:46 bpaauwe Exp $
 * $Author: bpaauwe $
 * $Date: 2006/10/04 05:21:46 $
 * ----------------------------------------------------------------------------
 *
 *  Copyright (c) Bob Paauwe (2006)
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 *  more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * ----------------------------------------------------------------------------
 *
 *  Description:
 *    Header file for insteon timer functions.  Timer entries are broken
 *    down into three tables. The tables start at address 0x1800 and are
 *    all in order. There was a refrence to timer tables at 0x3000 and
 *    0x4800 but those locations are empty in my PLC's So maybe they are
 *    overflow areas or maybe you could write one table to each area?
 *
 *    The first table is the timer table, it containes information on
 *    the trigger times for each event.  One field is the address of
 *    the command table for this event.
 *
 *    The command pointer table holds lists of commands that get executed
 *    for each event. This table is pretty simple, an id, count and
 *    addresses. Each address points to a command.
 *
 *   The command table has a type, a size, and the command. For Insteon
 *   commands it holds the 6 bytes (or 20 bytes for extended) that make
 *   up the command.  There doesn't seem to be any reason why this
 *   couldn't be a group command.
 *
 *   One interesting note is that in decoding a set of timers on a PLC,
 *   there are multiple timer events for the same time, these point to
 *   separate command pointer entries.  Why isn't there one timer event
 *   and multiple commands in the command pointer table?  Seems like that
 *   would be more efficient.
 *
 *   One issue is the size of the block of memory reserved for timers is
 *   unknown. It starts at 0x1800 but where does it end?  Is that what
 *   is located in 0x005a-0x005b?
 *
 * ----------------------------------------------------------------------------
 */
#ifndef _TIMERS_H
#define _TIMERS_H

#include "libilib/ilib.h"

#define MAX_CMDS 50  /* support for 50 commands per timer event */

/*
 * command description
 *   type  = type of command (insteon, x10, macro)
 *   len   = number of bytes
 *   data  = len number of bytes making up command
 */
typedef struct _timer_cmd {
	unsigned char type;
	unsigned char len;
	unsigned char *data;
} timer_cmd_t;

#define T_NONE    0x00
#define T_INSTEON 0x01
#define T_X10     0x02
#define T_RS232   0x03
#define T_VAR     0x04
#define T_MACRO   0x05


/*
 * cmd_group description
 *   id    = unique id, starts at 1
 *   count = number of commands in this group
 *   pos   = always 0 (what is this for?)
 *   cmd_ptrs = count number of addresses of commands.
 */
typedef struct _timer_cmd_group_t {
	unsigned char id;
	unsigned char count;
	unsigned char pos;
	unsigned short cmd_ptrs[MAX_CMDS];
	timer_cmd_t cmds[MAX_CMDS];
} timer_cmd_group_t;


/*
 * timerec description
 *   type  = type of record 00 = time, 01 = sunrise, 02 = sunset
 *   time  = absolute time or sunrise/sunset +/- time
 *   flag0 = 0x10 seems to be all that's used so far???
 *   dow   = day of week 0x0SSMTWTF (Sat, Sun, Mon, Tue, Wed, Thr, Fri)
 *   rpt   = repeat is always 0
 *   rpts  = repeat seconds is always 0
 *   cmd_group_id = address of command group
 *   filter_group_id = unused always 0x0000
 */
typedef struct _timer_timerec_t {
	int tid;
	unsigned char type;
	short time;
	unsigned char flag0;
	unsigned char dow;
	unsigned char rpt;
	unsigned char rpts;
	unsigned short cmd_group_id;
	unsigned short filter_group_id;
	timer_cmd_group_t cmd_group;
	struct _timer_timerec_t *next;
} timer_timerec_t;


#define T_ABSOLUTE 0x00
#define T_SUNRISE  0x01
#define T_SUNSET   0x02

#define T_SECURITY    0x80
#define T_RNDSECURITY 0x40
#define T_HOLIDAY     0x20
#define T_ACTIVE      0x10
#define T_DELETED     0x08
#define T_DEBUG       0x01

#define T_SATURDAY  0x40
#define T_SUNDAY    0x20
#define T_MONDAY    0x10
#define T_TUESDAY   0x08
#define T_WEDNESDAY 0x04
#define T_THURSDAY  0x02
#define T_FRIDAY    0x01


/*
 * Function prototypes
 */
void print_timer_record(timer_timerec_t *timer);
timer_timerec_t *get_timer_info(ilib_t *iplc);
int write_timers(ilib_t *iplc, timer_timerec_t *timers);
void load_timers(ilib_t *iplc, char *fname);
timer_timerec_t *parse_timer(char *line);
void clear_timers(ilib_t *iplc);
void free_timers(timer_timerec_t *timers);
void add_timer(timer_timerec_t *list, timer_timerec_t *new_timer);
void delete_timer(timer_timerec_t **list, int tid, int cid);

#endif
