#!/usr/sbin/perl
###
### ᥤ٥ȤΥ塼Ĥ
###
###
#
$dbfile = "schedule_event.lst";
$deffile = "m_ev_sche_def.h";
$datfile = "m_ev_sche_dat.h";

$defmax = 32;
$commax = 26;

open(DBF, $dbfile)
     || die "ǡ١򥪡ץǤޤ '$dbfile'\n";
$i = 0;
while(<DBF>){
    next if /^!/;
    ($comment, $label, $date, $time) = split;
    if($label ne ""){
        if($COMMENT{$label} eq ""){
            $COMMENT{$label} = $comment;
        }elsif(!($COMMENT{$label} =~  /etc$/)){
            $COMMENT{$label} = $COMMENT{$label}." etc";
        }
        $COMM[$i] = $comment;
        $LABEL[$i] = $label;
        $DATE[$i] = $date;
        $TIME[$i] = $time;
        $i++;
    }
}
close(DBF);
$max = $i;

#
##
##  إåե񤭽Ф
##
#
open(DEF, ">".$deffile) 
    || die "إåե򥪡ץǤޤ '$deffile'\n";
print DEF <<____DEF_HEAD;
/*
 ******************************************************************************
 *
 *	塼륤٥ȴ
 *
 ******************************************************************************
 */

#ifndef	__M_EV_SCHE_DEF_H__
#define	__M_EV_SCHE_DEF_H__

/*
** 塼륤٥ ** */
____DEF_HEAD
$i = 0;
foreach $key (sort keys(%COMMENT)){
    $enum = "EV_".$key;
    printf(DEF "#define %-${defmax}s (%3d) /* %-${commax}s */\n",  $enum, $i, $COMMENT{$key});
    $i++;
}
printf(DEF "#define %-${defmax}s (%3d) /* %-${commax}s */\n\n", "EV_SCHEDULE_NO_END", $i, "ʾ");
printf(DEF "#define EV_SCHEDULE_TYPE_MAX   EV_SCHEDULE_NO_END\n\n\n");

printf(DEF "#if defined(USE_EVENT_COMMENT_4_DEBUG) && defined(__M_EVENT_C__)\n");
printf(DEF "/*\n** ǥХåʸ ** */\nconst char *event_comment[EV_SCHEDULE_TYPE_MAX] = {\n");
foreach $key (sort keys(%COMMENT)){
    printf(DEF "   \"%s\",\n",  $COMMENT{$key});
    $i++;
}
printf(DEF "};\n#endif\n\n");

print DEF <<____DEF_TAIL;

/*
** --- 塼֥ --- 
*/
typedef struct _event_date_data_ {
    char  month, day, flag, hour;
} evdate_t;

typedef struct _event_schedule_ {
    union _event_schedule_date_ {
	evdate_t d;               /* ջ */
	unsigned short v;         /* ƥߴʤ */
	unsigned long lv;
    } from, to;
    int type;
} EvSchedule;

typedef union _event_schedule_date_ evdate_u;

#if defined(__M_EVENT_C__)
#define is_normalday_data(flag)   ((flag) == 0)      /* ǡ */
#define is_kyureki_data(flag)     ((flag) & 0x08)    /* 񤫡 */
#define is_week_data(flag)        ((flag) & 0x01)    /* ꤫ */
#define is_every_data(flag)       ((flag) & 0x06)    /* 衩ǡ */
#define is_everyweek_data(flag)   ((flag) & 0x02)    /* 轵ǡ */
#define is_everymonth_data(flag)  ((flag) & 0x04)    /* ǡ */
#define day_of_week(day)          ((day) & 0x07)     /* å */
#define cycle_of_week(day)        (((day) & 0xf8) >> 3) /* ܤ */
#endif
/* flag */
#define EV_FLG_WDAY               (0x01)  /*  */
#define EV_FLG_WEEKLY             (0x02)  /* 轵 */
#define EV_FLG_MONTHLY            (0x04)  /*  */
#define EV_FLG_JPOLD              (0x08)  /*  */
#define EV_FLG_PROGRAM            (0x10)  /* ץǤ */
#define EV_FLG_NDAYS              (0x40)  /* ³ֻ */
#define EV_FLG_DAILYTIME          (0x80)  /* ֻ꤬ñ */
#define EV_FLG_MASK_DATE          ~(EV_FLG_DAILYTIME)
/* alias */
#define EV_DATE_MONTH_DAY         (0x00)  /*  */
#define EV_DATE_MONTH_N_WDAY      (0x01)  /*  */
#define EV_DATE_MONTH_WEEKLY      (0x03)  /* 轵 */
#define EV_DATE_DAY               (0x04)  /*  */
#define EV_DATE_N_WDAY            (0x05)  /*  */
#define EV_DATE_WEEKLY            (0x07)  /* 轵 */
#define EV_DATE_JP_MONTH_DAY      (0x08)  /* 񡩷 */
#define EV_DATE_PROGRAM_DAY       (0x10)  /* ץǤ */
#define EV_DATE_NDAYS             (0x40)  /* ³ֻ */

/*
**  ** */
#define EV_WEEK_SUNDAY    (0)
#define EV_WEEK_MONDAY    (1)
#define EV_WEEK_TUESDAY   (2)
#define EV_WEEK_WEDNESDAY (3)
#define EV_WEEK_THURSDAY  (4)
#define EV_WEEK_FRIDAY    (5)
#define EV_WEEK_SATURDAY  (6)
#define EV_WEEK_ANYDAY    (7)  /* Ǥ */

/*
** 衩 ** */
#define EV_WEEK_FIRST     (0x01)
#define EV_WEEK_SECOND    (0x02)
#define EV_WEEK_THIRD     (0x03)
#define EV_WEEK_FOURTH    (0x04)
#define EV_WEEK_FIFTH     (0x05)
#define EV_WEEK_LAST      (0x0f)  /* ǽ */
#define EV_WEEK_EVELY     (0x10)  /* 轵 */


#endif /* __M_EV_SCHE_DEF_H__ */

____DEF_TAIL
close(DEF);

#
##
##  ǡإåե񤭽Ф
##
#
open(DAT, ">".$datfile) 
    || die "إåե򥪡ץǤޤ '$datfile'\n";
print DAT <<____DAT_HEAD;
/*
 ******************************************************************************
 *
 *	塼륤٥ȴʥǡ
 *
 ******************************************************************************
 */

#ifndef	__M_EV_SCHE_DAT_H__
#define	__M_EV_SCHE_DAT_H__
#ifdef  __M_EVENT_C__ 
#include "$deffile"

____DAT_HEAD
printf(DAT "static EvSchedule event_schedule_data[] =  {\n");
for($i = 0; $i < $max; $i++){
    $enum = "EV_".$LABEL[$i];

    $from = &make_from_data($DATE[$i], $TIME[$i]);
    $to = &make_to_data($DATE[$i], $TIME[$i]);
    printf(DAT "  /* *** %s *** %s %s *** */\n", $COMM[$i], $DATE[$i], $TIME[$i]);
    printf(DAT "  { %s, %s, %s },\n", $from, $to, $enum);
}
printf(DAT "};\n#define EV_SCHEDULE_DATA_MAX  (%d)\n", $max);

print DAT <<____DAT_TAIL;
#endif /* __M_EVENT_C__ */
#endif /* __M_EV_SCHE_DAT_H__ */

____DAT_TAIL
close(DAT);

exit(0);

#
##
##  ֥롼
##
#
sub make_from_data {
    local($date, $time) = @_;
    local($ss) = "{ ";
    if(($pos = index($date, "-")) >= $[){
        $ss .= &check_date(substr($date, 0, $pos), 1);
    }else{
        $ss .= &check_date($date, 1);
    }
    $ss .= ", ";
    if(($pos = index($time, "-")) >= $[){
        $ss .= &check_time(substr($time, 0, $pos), 1);
    }else{
        $ss .= &check_time($time, 1);
    }
    $ss .= " }";
    return  $ss;
}

sub make_to_data {
    local($date, $time) = @_;
    local($ss) = "{ ";
    if(($pos = index($date, "-")) >= $[){
        $ss .= &check_date(substr($date, $pos + 1), 0);
    }else{
        $ss .= &check_date($date, 0);
    }
    $ss .= ", ";
    if(($pos = index($time, "-")) >= $[){
        $ss .= &check_time(substr($time, $pos + 1), 0);
    }else{
        $ss .= &check_time($time, 0);
    }
    $ss .= " }";
    return  $ss;
}

sub check_time {
    local($time, $dir) = @_;
    local($ss) = "";
    if($time =~ /^$/){
	$ss .= sprintf("%d", ($dir ? 0 : 23));
    }elsif($time =~ /^$/){
	$ss .= sprintf("%d", ($dir ? 0 : 11));
    }elsif($time =~ /^$/){
	$ss .= sprintf("%d", ($dir ? 12 : 23));
    }elsif($time =~ /^([0-9][0-9])(:00|)$/){
        $ss .= sprintf("%d", $1);
    }elsif($time =~ /^([0-9][0-9])(:|)([0-9][0-9])(ʬ)?$/){
        print STDERR "ʬϥݡȤƤޤ󡣻ñ̤ˤƤ\n";
        $ss .= sprintf("%d", $1);
    }else{
        print STDERR "֥ǡǤ($time)\n";
        $ss .= "99";
    }
    return  $ss;
}

sub check_date {
    local($date, $dir) = @_;
    local(%weekd) = (
        "", 0,        "", 1,        "", 2,
        "", 3,        "", 4,        "", 5,
        "", 6,        "", 7
    );
    local (%weekn) = (
        "轵", 0x10, "ǽ", 0x0f,
        "裱", 0x01, "裲", 0x02, "裳", 0x03, "裴", 0x04, "裵", 0x05
    );
    local (%weekf) = (
        "轵", 3, "ǽ", 1,
        "裱", 1, "裲", 1, "裳", 1, "裴", 1, "裵", 1
    );
    local($ss) = "";
    if($date =~ /^ǯ$/){
	$ss .= sprintf("%d,%d, 0", ($dir ? 1 : 12), ($dir ? 1 : 31));
    }elsif($date =~ /^ץ$/){
	$ss .= sprintf("%d,%d, 128", ($dir ? 1 : 12), ($dir ? 1 : 31));
    }elsif($date =~ /^([0-9][0-9])(\/|)([0-9][0-9])()?$/){
        $ss .= sprintf("%d,%d, 0", $1, $3);
    }elsif($date =~ /^([0-9]+)$/){
        $ss .= sprintf("0,%d, 64", $1);
    }elsif($date =~ /^([0-9][0-9])()?$/){
        $ss .= sprintf("%d,%d, 4", 15, $1);
    }elsif($date =~ /^()?([0-9][0-9])(\/|)([0-9][0-9])()?$/){
        $ss .= sprintf("%d,%d, 8", $2, $4);
   }elsif($date =~ /^([0-9][0-9])()?(轵|ǽ|裱|裲|裳|裴|裵)(|||||||)()?$/){
        $ss .= sprintf("%d,0x%02x, %d", $1, ($weekn{$3} << 3) | ($4 eq "" ? ($dir ? $weekd{''} : $weekd{''}) : $weekd{$4}), $weekf{$3});
    }elsif($date =~ /^()?(轵|ǽ|裱|裲|裳|裴|裵)(|||||||)()?$/){
        $ss .= sprintf("%d,0x%02x, %d", 15, ($weekn{$2} << 3) | ($3 eq "" ? ($dir ? $weekd{''} : $weekd{''}) : $weekd{$3}), $weekf{$2} | 4);
    }else{
        print STDERR "եǡǤ($date)\n";
        $ss .= "0x00, 99,99";
    }
    return  $ss;
}
