#!/usr/bin/perl

require 'ctime.pl';

# Prototypical email browsing
%emailbrowse = ('Up', 5,
		'Down', 3,
		'Return', 3,
		115, 1, # s
		113, 1, #q
		69, 1, # E
		110, 1, # n
		121, 1); #y

%emailbrowse = &normalize(%emailbrowse);

%codingperl = ('Shift_R', 6.25,
	       'Down', 6.25,
	       'Up', 4.25,
	       32, 3.75, # Space
	       99, 3.25, # c
	       'Right', 3,
	       'Left', 2.5,
	       101, 2.75, # e
	       'Return', 2.25,
	       36, 2, # $
	       9, 1.75); # TAB

%codingperl = &normalize(%codingperl);

%webbrowsing = ('WindowSwitch', 1.25,
		'Next', 1.25,
		'Alt_L', .75,
		'Up', .75,
		'Control_L', .5,
		'Down', .5,
		'Prior', .25,
		'Left', .25);

%webbrowsing = &normalize(%webbrowsing);

%futzing = ('WindowSwitch', 7,
	    'Return', 1.5,
	    'Alt_L', 1.25,
	    9, .75, # TAB
	    'Up', .5);

%futzing = &normalize(%futzing);

%english = ('Space', 12,
	    111, 6, # o
	    101, 6, # e
	    116, 4.75, # t
	    105, 4.25, #i
	    127, 4, # BS
	    110, 3.5, # n
	    97, 3.5, #a
	    115, 3); #s

%english = &normalize(%english);
	    
%prototypes = (\%emailbrowse, 'Email Browsing',
	       \%codingperl, 'Coding Perl',
	       \%webbrowsing, 'Web Browsing',
	       \%futzing, 'Futzing',
	       \%english, 'Writing English Text',
	       );

@prototypes = (\%emailbrowse, \%codingperl, \%webbrowsing, \%futzing,
	       \%english );


select(STDIN); $|=1; select(STDOUT);
while(<>){
    $time = time();
    ($type, $v, @rest) = split;
    if($type eq "WindowSwitch"){
	$ev = "WindowSwitch";
    }
    else{
	$ev = $v;
    }
    push(@tl, $time);
    push(@e, $ev);
    $ct{$ev}++;
    $ct++;

    $slot = 0;
    $silentperiod = 1;
    while($tl[0] < $time-15){
	if(!defined $lact){
	    $lact = "Nothing";
	    $ltime = $time;
	}
	$ot = shift(@tl);
	shift(@e);
	$slot = 1;
	$silence = ($time-$ot-15);
	if(($silence > 5) && $silentperiod){
	    chop($when = &ctime($ot));
	    print "---> $when Silence $silence\n";
	    if($silence > 70){
		$lact = "Away";
		$ltime = $ot;
	    }
	    $silentperiod = 0;
	}
    }
    if($slot){
	&id(@e);
#	&dist(@e);
    }

    if($ct%1000 == 0){
	@topk = sort { $ct{$a} <=> $ct{$b}; } keys %ct;
	print "=================================\n";
	for $k (@topk){
	    if(int($k) != 0){
		$c = pack("c", $k);
		$c = "Backspace" if($k == 8);
		$c = "TAB" if($k == 9);
		$c = "Space" if($k == 32);
		$c = "Backspace" if($k == 8);
		    
		print "$ct{$k} presses of $c ($k)\n";
	    }
	    else{
		print "$ct{$k} presses of $k\n";
	    }
	}
    }
}

sub id {
    my @e = @_;
    my %cure= ();
    my %calced = ();
    $mindist = 100000;
    $maxproj = 0;
    for $h (@e){
	$cure{$h}++;
    }

#    %cure = &normalize(%cure);

    for $p (@prototypes){
	%prot = %{$p};
	@pfoo = keys %prot;
	%calced = ();
	$distance = 0;
#	print "Analazying correlation for $prototypes{$p}\n";
	foreach $pk (keys %prot){
#	    $distance += abs($prot{$pk}-$cure{$pk});
#	    print "\t$pk : $prot{$pk} $cure{$pk}\n";
	    $distance += abs($prot{$pk}*$cure{$pk});
	    $calced{$pk} = 1;
	}
	foreach $pk (keys %cure){	
	    next if $calced{$pk};
#	    print "\t$pk : $prot{$pk} $cure{$pk}\n";
#	    $distance += abs($prot{$pk}-$cure{$pk});
	    $distance += abs($prot{$pk}*$cure{$pk});
	}
#	print "Distance to $prototypes{$p} is $distance\n";
	$a = $prototypes{$p};
	$d{$a} = $distance;
	$act{$a} /=4;
	$act{$a} += $d{$a};
	if($distance > $maxproj){
	    $activity = $prototypes{$p};
#	    $mindist = $distance;
	    $maxproj = $distance;
	}
    }

    if(0) {
    $tot = 0;
    for $a (keys %act){
	$tot+=$act{$a};
    }
    print "\n";
    for $a (keys %act){
	$prob = int(100*$act{$a}/$tot);
	$fa = $a.(" " x (30-length($a)));
	print "$fa\t\t$prob %\t$d{$a}\n";
    }    
}
    chop($when = &ctime($time));
    if($activity ne $lact){
	$budget{$lact}+=($time-$ltime);
	$tt=0;
	for $la (keys %budget){
	    $tt+= $budget{$la};
	    print "Activity $la used $budget{$la} seconds\n";
	}
	print "Total time period: $tt\n";
	$tt=1 if ($tt == 0);
	print "Summary ";
	for $la (keys %budget){
	    print "[ $la ", int(100*$budget{$la}/$tt), "%] ";
	}
	print "\n";
    }
    if($maxproj > 1){
	print "---> $when $activity ($maxproj)\n" unless ($activity eq $lact);
	$ltime = $time unless ($activity eq $lact);
	$lact = $activity;
    }
}

sub dist {
    my @p = @_;
    $dist++;
    for $p (@p){
	$hits{$p}++;
    }
    @topk = sort { $hits{$a} <=> $hits{$b}; } keys %hits;
    print "-----------------------------\n";
    for $k (@topk){
	if(int($k) != 0){
	    $c = pack("c", $k);
	    $c = "Backspace" if($k == 8);
	    $c = "TAB" if($k == 9);
	    $c = "Space" if($k == 32);
	    $c = "Backspace" if($k == 8);
	    
	    print $hits{$k}/$dist, "  $c ($k)\n";
	}
	else{
	    print $hits{$k}/$dist, "  $k\n";
	}
    }
}

sub normalize {
    my %p = @_;
    my %n = ();
    $mag=0;
    for $k (keys %p){
	$mag += $p{$k}*$p{$k};
    }
    $mag = sqrt($mag);
    for $k (keys %p){
	$n{$k} = $p{$k}/$mag;
    }
    return %n;
}

__END__

Long term values:

81 presses of . (46)
82 presses of Alt_L
83 presses of w (119)
89 presses of c (99)
90 presses of m (109)
95 presses of d (100)
101 presses of u (117)
108 presses of TAB (9)
110 presses of Right
112 presses of 
                (11)
121 presses of r (114)
147 presses of h (104)
152 presses of l (108)
160 presses of Down
175 presses of s (115)
180 presses of  (127)
186 presses of Up
192 presses of i (105)
201 presses of n (110)
202 presses of Shift_R
204 presses of a (97)
237 presses of o (111)
257 presses of Return
300 presses of t (116)
352 presses of e (101)
427 presses of WindowSwitch
722 presses of Space (32)
