#!/usr/bin/env perl
use strict;
use warnings;

use GD;
use DateTime;

my $width  = 500;
my $height = 600;

my %margin = (left => 30, right => 20, top => 20, bottom => 20);
my @days = qw(Mon Tue Wed Thu Fri Sat Sun);

my $cellw = ($width - $margin{left} - $margin{right})/7;
my $cellh = ($height - $margin{top} - $margin{bottom})/24;

my $top = $margin{top};
my $left = $margin{left};
my $right = $width - $margin{right};
my $bot = $height - $margin{bottom};

my $image = GD::Image->new($width, $height, 1);
$image->alphaBlending(1);

my @log;

sub cmp_rec {
    my $a = shift;
    my $b = shift;
    return ($a->[1] <=> $a->[1])
        || ($a->[2] <=> $a->[2]);
}

sub day {
    return shift->[1] - 1;
}

sub hour {
    return shift->[2];
}

sub writeImage {
    my $im = shift;
    my $fn = shift;
    open(my $fh, ">", $fn);
    print $fh $im->png;
    close($fh);
}

sub create_calendar {
    my $image = shift;

    my $white = $image->colorAllocate(0xFF,0xFF,0xFF);
    my $black = $image->colorAllocate(0x00,0x00,0x00);

    $image->filledRectangle(0, 0, $width, $height, $white);

    for my $row (0..24) {
        $image->line($left, $top+$row*$cellh, $right, $top+$row*$cellh, $black);
        if($row != 24) {
            $image->string(gdSmallFont, $margin{left}/2, $top+$row*$cellh, "$row", $black);
        }
    }

    for my $col (0..7) {
        $image->line($left+$col*$cellw, $top,
                     $left+$col*$cellw, $bot, $black);
        if($col != 7) {
            $image->string(gdSmallFont,
                           $left+$col*$cellw, 2,
                           $days[$col], $black);
        }
    }
}

open(my $log, "<", shift || "log");

while(my $rec = <$log>) {
    next if $rec =~ /^#/;
    my ($state, $time, undef) = split /,/, $rec;
    my $date = DateTime->from_epoch(epoch => $time, time_zone => 'America/New_York');
    push @log, [$state, $date->day_of_week, $date->hour + ($date->minute/60)];
}

close($log);

# @log = sort {cmp_rec($a,$b)} @log;

create_calendar($image);

my $grn = $image->colorAllocate(0,0xFF,0);
my $red = $image->colorAllocate(0xFF,0,0);

for my $ent (@log) {
    $image->line($left+$cellw*day($ent),
                 $top+hour($ent)*$cellh,
                 $left+$cellw*(1+day($ent)),
                 $top+hour($ent)*$cellh,
                 $ent->[0] ? $grn : $red);
}

writeImage($image, "openclose.png");


create_calendar($image);
my $color = $image->colorAllocateAlpha(0x00,0xFF,0x00,0x68);

my @ints;
my $last = [0,1,0];
for my $ent (@log) {
    #warn join(":", @$ent);
    if(!$ent->[0]) {
        # We have a close edge, draw it
        if(day($ent) != day($last)) {
            draw_rect($image, $last, [1, day($last)+1, 24], $color);
            draw_rect($image, [1, day($ent)+1, 0], $ent, $color);
        } else {
            draw_rect($image, $last, $ent, $color);
        }
    } else {
        $last = $ent;
    }
}


sub draw_rect {
    my $im = shift;
    my $fst = shift;
    my $snd = shift;
    my $color = shift;
    $im->filledRectangle($left+day($fst)*$cellw + 1,
                         $top +hour($fst)*$cellh,
                         $left+(day($fst)+1)*$cellw - 1,
                         $top +hour($snd)*$cellh,
                         $color);
}

writeImage($image, "door.png");
