#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys,os
import re
import time
import math
from optparse import OptionParser


KEYINFO =  [ 
			[
				[0, 50, "~", "ˇ", "¬","¬"],  [1, 40, "!", "1" ,"¡", "¹"],[2, 40, '"', "2", "⅛", "@"], [3, 40, "#", "3", "£","£"],[4, 40, "¤", "4", "$","$"],  [5, 40, "%", "5", "⅜","½"],
                [6, 45, "&", "6", "⅝","¬"],  [7, 40, "/", "7", "⅞","{"], [8, 40, "(", "8", "™", "["], [9, 40, ")", "9","±", "]"], [10, 40, "=", "0", "°", "}"],[11, 40, "?", "+", "¿", "\\"],
                [12, 45, "`", "´","'", "`" ],[13, 60, ""]
            ],
            [    
                [14, 30, "", "\t"], [15, 20, "Q", "q", "Ω","@"],  [16, 20, "W", "w","Ł","ł"],[17, 20, "E", "e", "¢", "€"],[18, 20, "R", "r", "®", "¶"], [19, 25, "T", "t", "Ŧ", "ŧ"],
                [20, 30, "Y", "y","¥","←"], [21, 20, "U", "u","↑","↓"],  [22, 20, "I", "i","ı", "→"],[23, 20, "O", "o", "Ø", "ø"],[24, 20, "P", "p", "Þ", "þ"],[25, 25, "Ü", "ü", "°", "¨"],
                [26, 40, "Õ", "õ","¯","§"]
            ],
            [    
                [28, 20, ""],      [29, 0, "A", "a","Æ","æ"],[30, 0, "S", "s", "Š", "š"],[31, 0, "D", "d", "Ð", "ð"],[32, 0, "F", "f", "ª", "đ"], [33, 20, "G", "g", "Ŋ", "ŋ"],
                [34, 20, "H", "h", "Ħ", "ħ"],[35, 0, "J", "j", "J", "j"],[36, 0, "K", "k", "&", "ĸ"],[37, 0, "L", "l", "Ł", "ł"],[38, 0, "Ö", "ö", "˝", "´"],[39, 19, "Ä", "ä", "ˇ", "^"],
                [61, 38, "*", "'", "˘", "½"],[40, 55, "", "\n"]
            ],
            [    
                [41, 32, "", "lshift"],[27, 20, ">", "<", "¦", "|"],[42, 20, "Z", "z","Ž", "ž"],[43, 20, "X", "x",  ">", "»"],[44, 20, "C", "c", "©", "¢"],[45, 20, "V", "v","‘", "“"], [46, 35, "B", "b", "’", "”"],
                [47, 22, "N", "n", "N", "n"],[48, 20, "M", "m", "º", "µ"],[49, 20, ";", ",","×", "<"],[50, 20, ":", ".", "÷", ">"],[51, 20, "_", "-","", ""],[52, 23, "", "rshift"],
            ],
            [    
                [53, "4_0", ""],[54, "4_1", ""],[55, "4_2", ""],[56, 0, " ", " "],[57, 20, "", "altgr"],[58, "4_5", ""],[59, "4_6", ""],[60, "4_7", ""]
			]
           ]
  
KEYMAPS = {'querty': 
	[[0,1,2,3,4,5,6,7,8,9,10,11,12,13],
	[14,15,16,17,18,19,20,21,22,23,24,25,26],
	[28,29,30,31,32,33,34,35,36,37,38,39,40],
	[41,27,42,43,44,45,46,47,48,49,50,51,52],
	[53,54,55,56,57,58,59]
	]
}

  #~ This array indicates a mapping of fingers to keys
  #~ 0 = thumb
  #~ 1 = left pinky
  #~ 2 = left ring finger
  #~ 3 = left middle finger
  #~ 4 = left index finger
  #~ 5 = right index finger
  #~ 6 = right middle finger 
  #~ 7 = right ring finger
  #~ 8 = right pinky

KEY_TO_FINGER = [[1,1,1,2,3,4,4,5,5,6,7,8,8,8],
				 [1,1,2,3,4,4,5,5,6,7,8,8,8],
				 [1,1,2,3,4,4,5,5,6,7,8,8,8,8], 
				 [1,1,1,2,3,4,4,5,5,6,7,8,8],
				 [4,4,0,0,0,5,5,5] 
                ]



fingerUsagePoints = [0, 2, 3, 4, 1, 2, 4, 3, 1]
rowUsagePoints = [1, 3, 4, 2, 0]
#AltGr, AltGr + Shift
altGrUsagePoints = [-1, -2]

OUTFILE = "speed.txt"

NORMAL = 0
SHIFT = 1
ALTGR = 2

key_to_print = {
			' ':'space',
			'\n':'enter',
			'.':'dot',
			',':'comma',
			'-':'hpen', 
			':':'colon', 
			';':'scolon', 
			'!':'excl', 
			'?':'quest', 
			'/':'slash', 
			'_':'uscore', 
			"'":'upcomma',	
			}

print_to_key = dict()	
for key, val in key_to_print.iteritems():
	print_to_key[val] = key

def keyhash():
	prop = {'row': False, 'col': False, 'mod':0, 'distance':0, 'finger':False}
	keyhash = dict()
	for i in range(len(KEYINFO)):
		row = KEYINFO[i]
		for j in range(len(row)):
			button = row[j]
			p = prop.copy()
			p['row'] = i
			p['col'] = j
			p['finger'] = KEY_TO_FINGER[i][j]
			p['distance'] = button[1]
					 
		
			if len(button)>3 :
				p['mod'] = SHIFT
				if button[2] not in keyhash:
					keyhash[button[2]] = p
				
				p = p.copy()
				p['mod'] = NORMAL
				if button[3] not in keyhash:
					keyhash[button[3]] = p
					
			if len(button) > 5:
				
				p = p.copy()
				p['mod'] = SHIFT + ALTGR
				if button[4] not in keyhash:
					keyhash[button[4]] = p
				
				p = p.copy()
				p['mod'] = ALTGR
				if button[5] not in keyhash:
					keyhash[button[5]] = p
			
	return keyhash
		


def main(argv=None):

	if argv is None:
		argv = sys.argv[1:]
		
	parser = OptionParser(usage = "usage: %prog [options] FILE1 ...", version="%prog 0.1")
	#parser.add_option('-q', '--quiet',  action="store_false", dest = 'verbose', default=True, help="don't print status messages to stdout")
	parser.add_option('-f', '--file', dest='out_filename', default=OUTFILE, metavar="FILE", help="output file name")

	(options, datafiles) = parser.parse_args(args = argv)
	
	for filename in datafiles:
		f = file(filename, "r")
		
		lines = []
		for line in f:
			line = line.rstrip()
			lines.append(line.split("\t"))
			
		stats = dict()

		
		for i in range(1,len(lines)):
			
			next = dict()
			for j in range(1,len(lines[i])):
				next[print_to_key.get(lines[0][j],lines[0][j])] = int(lines[i][j])
		
			stats[print_to_key.get(lines[i][0],lines[i][0])] = next
		f.close()	
		
	#~ for prev, row in stats.iteritems():
		#~ print "'%s': {" % prev,
		#~ for next, val in row.iteritems():
			#~ print "'%s': %s," % (next,val),
		#~ print "},",
		
	khash = keyhash()
	
	fingerUsage = [0,0,0,0,0,0,0,0,0]
	rowUsage = [0,0,0,0,0]

	keyCount = dict()
	keyCount['rshift'] = 0
	keyCount['lshift'] = 0
	keyCount['altgr'] = 0
	keyCount['sameHand'] = 0
	keyCount['sameFinger'] = 0
	keyCount['neighFinger'] = 0
	keyCount['distance'] = 0
	time_start = time.time()
	for prev, row in stats.iteritems():
		if prev in khash:
			fingerUsage[khash[prev]['finger']] += row['count']
			rowUsage[khash[prev]['row']] += row['count']
			
			if khash[prev]['mod'] & ALTGR:
				keyCount['altgr'] += row['count']
			
			if (khash[prev]['mod'] & SHIFT):
				if (0<khash[prev]['finger']<5):
					keyCount['rshift'] += row['count']
				if  (4<khash[prev]['finger']<9):
					print prev, khash[prev], row['count']
					keyCount['lshift'] += row['count']

							
			for next, val in row.iteritems():
				if next in khash:
					if prev != next and next != 'count':
						
						keyCount['distance'] += (khash[prev]['distance']+khash[next]['distance'])*val
						#~ if val > 0:
							#~ print "'%s': %s, '%s': %s > %s" % (prev, khash[prev]['distance'], next ,khash[next]['distance'], (khash[prev]['distance'] + khash[next]['distance']))
								
						if ((0<khash[prev]['finger']<5) and (0<khash[next]['finger']<5)) or ((4<khash[prev]['finger']<9) and (4<khash[next]['finger']<9)):
							keyCount['sameHand'] += val
							if khash[prev]['finger'] == khash[next]['finger']:
								keyCount['sameFinger'] += val
							if abs(khash[prev]['finger']-khash[next]['finger']) == 1:
								keyCount['neighFinger'] += val
								
	keyCount['distance'] += 2*(keyCount['rshift']*khash['rshift']['distance'] + keyCount['lshift']*khash['lshift']['distance'] + keyCount['altgr']*khash['altgr']['distance'])

	time_end = time.time()
	print "Took time %.5f minutes" % ((time_end - time_start) /60.)
	print fingerUsage
	print rowUsage
	print keyCount
	
if __name__ == "__main__":
	sys.exit(main())
