#perl analog console clock

$DO_SECOND_HAND = 0;

$size = shift;
$hpv = shift;

if (!$size) {
  print "Usage: $0 [vertical-radius] [horiz_per_vert]\n";
  print "default: 12 = vertical-radius, 1.5 = horiz_per_vert\n";
  print "Re-size your window until it looks right.\n";
  print "Type <Enter> to continue\n";
  $resp = <STDIN>;
}

$size = 12 unless $size;
$hpv = 1.5 unless $hpv;
$hsize = $hpv*$size;

$hour_hand_size = 0.62;
$min_hand_size = 0.9;
$sec_hand_size = 0.9;

# make middle marker
$face{'0,0'} = '+';

# make minute tic marks
foreach $min (1..60) {
  $cr = cos(2*3.1415927*($min)/60);
  $sr = sin(2*3.1415927*($min)/60);
  $hl=2*$size;
  $hx = $cr*$hl/2;
  $hx = int($hx + 0.5) if $hx > 0;
  $hx = int($hx - 0.5) if $hx < 0;
  $hy = $sr*$hl*$hpv/2;
  $hy = int($hy + 0.5) if $hy > 0;
  $hy = int($hy - 0.5) if $hy < 0;
  $gp = $hy.','.(0-$hx);
  $face{$gp} = '*';
}
# make hour tic marks
foreach $hour (1..12) {
  $cr = cos(2*3.1415927*($hour)/12);
  $sr = sin(2*3.1415927*($hour)/12);
  foreach $hl (2*$size-1..2*$size) {
  $hx = $cr*$hl/2;
  $hx = int($hx + 0.5) if $hx > 0;
  $hx = int($hx - 0.5) if $hx < 0;
  $hy = $sr*$hl*$hpv/2;
  $hy = int($hy + 0.5) if $hy > 0;
  $hy = int($hy - 0.5) if $hy < 0;
  $gp = $hy.','.(0-$hx);
  $face{$gp} = '#';
  }
}

@cls_cmd = ("cls");
while (1) {
  $t1 = time;
  ($sec,$min,$hour) = localtime $t1;
  
  # redraw clock
  %graph = %face;

  if ($DO_SECOND_HAND) {
  # second hand
  $cr = cos(2*3.14159*$sec/60);
  $sr = sin(2*3.14159*$sec/60);
  if ($hpv*abs($sr) > abs($cr)) {
    #find each vert per horiz
    if ($sr>0) {
      $gst = 2;
      $gfn = $sec_hand_size*abs($sr)*$hsize;
      $gfn = int($gfn + 0.5);
    } else {
      $gst = -$sec_hand_size*abs($sr)*$hsize;
      $gst = int($gst - 0.5);
      $gfn = -2;
    }
    foreach $hy ($gst..$gfn) {
      $hx = $hy*$cr/$sr/$hpv;
      $hx = int($hx + 0.5) if $hx > 0;
      $hx = int($hx - 0.5) if $hx < 0;
      $gp = $hy.','.(0-$hx);
      $graph{$gp} = '.';
    }
  } else {
    #find each horiz per vert
    if ($cr<0) {
      $gst = -$sec_hand_size*abs($cr)*$size;
      $gst = int($gst - 0.5);
      $gfn = -2;
    } else {
      $gst = 2;
      $gfn = $sec_hand_size*abs($cr)*$size;
      $gfn = int($gfn + 0.5);
    }
    foreach $hx ($gst..$gfn) {
      $hy = $hpv*$hx*$sr/$cr;
      $hy = int($hy + 0.5) if $hy > 0;
      $hy = int($hy - 0.5) if $hy < 0;
      $gp = $hy.','.(0-$hx);
      $graph{$gp} = '.';
    }
  }
  }

  # minute hand
  $cr = cos(2*3.14159*$min/60);
  $sr = sin(2*3.14159*$min/60);
  if ($hpv*abs($sr) > abs($cr)) {
    #find each vert per horiz
    if ($sr>0) {
      $gst = 2;
      $gfn = $min_hand_size*abs($sr)*$hsize;
      $gfn = int($gfn + 0.5);
    } else {
      $gst = -$min_hand_size*abs($sr)*$hsize;
      $gst = int($gst - 0.5);
      $gfn = -2;
    }
    foreach $hy ($gst..$gfn) {
      $hx = $hy*$cr/$sr/$hpv;
      $hx = int($hx + 0.5) if $hx > 0;
      $hx = int($hx - 0.5) if $hx < 0;
      $gp = $hy.','.(0-$hx);
      $graph{$gp} = 'o';
    }
  } else {
    #find each horiz per vert
    if ($cr<0) {
      $gst = -$min_hand_size*abs($cr)*$size;
      $gst = int($gst - 0.5);
      $gfn = -2;
    } else {
      $gst = 2;
      $gfn = $min_hand_size*abs($cr)*$size;
      $gfn = int($gfn + 0.5);
    }
    foreach $hx ($gst..$gfn) {
      $hy = $hpv*$hx*$sr/$cr;
      $hy = int($hy + 0.5) if $hy > 0;
      $hy = int($hy - 0.5) if $hy < 0;
      $gp = $hy.','.(0-$hx);
      $graph{$gp} = 'o';
    }
  }

  # hour hand
  $cr = cos(2*3.14159*($hour+$min/60)/12);
  $sr = sin(2*3.14159*($hour+$min/60)/12);
  if ($hpv*abs($sr) > abs($cr)) {
    #find each vert per horiz
    if ($sr>0) {
      $gst = 2;
      $gfn = $hour_hand_size*abs($sr)*$hsize;
      $gfn = int($gfn + 0.5);
    } else {
      $gst = -$hour_hand_size*abs($sr)*$hsize;
      $gst = int($gst - 0.5);
      $gfn = -2;
    }
    foreach $hy ($gst..$gfn) {
      $hx = $hy*$cr/$sr/$hpv;
      $hx = int($hx + 0.5) if $hx > 0;
      $hx = int($hx - 0.5) if $hx < 0;
      $gp = $hy.','.(0-$hx);
      $graph{$gp} = 'O';
    }
  } else {
    #find each horiz per vert
    if ($cr<0) {
      $gst = -$hour_hand_size*abs($cr)*$size;
      $gst = int($gst - 0.5);
      $gfn = -2;
    } else {
      $gst = 2;
      $gfn = $hour_hand_size*abs($cr)*$size;
      $gfn = int($gfn + 0.5);
    }
    foreach $hx ($gst..$gfn) {
      $hy = $hpv*$hx*$sr/$cr;
      $hy = int($hy + 0.5) if $hy > 0;
      $hy = int($hy - 0.5) if $hy < 0;
      $gp = $hy.','.(0-$hx);
      $graph{$gp} = 'O';
    }
  }

  $min = '0'.$min if $min < 10;
  $hour = '0'.$hour if $hour < 10;
  system @cls_cmd;
  print "$hour:$min\n"; # digital display
  foreach $gv (-$size..$size) {
    foreach $gh (-$hsize-1..$hsize) {
      $gp = $gh.','.$gv;
      if ($graph{$gp}) {
        print $graph{$gp};
      } else {
        print ' ';
      }
    }
    print "\n";
  }

  if ($DO_SECOND_HAND) {
    $update = 1;
  } else {
    $update = 61 - $sec; #aim to get time at 1 sec after the minute
  }
  sleep($update);

}