#!/usr/bin/python
import os,sys,re,random

random.seed()

class String:

  def __init__(self, s):
    self.s = s
    self.occ = 1

  def score(self):
    if '_score' not in self.__dict__:
      self._score = (len(self.s)-1) * (self.occ-1)
    return self._score

  def __cmp__(self, other):
    return - self.score().__cmp__(other.score())

  def __str__(self):
    return '%3d %2d "%s"' % (self.score(), self.occ, self.s)

  def substring(self, other):
    return other.s.find(self.s) > -1

def analyze(program):
  # count string occurrences
  strings = {}
  for i in range(2,16):
    for k in range(0,len(program)-i+1):
      s = program[k:k+i]
      if s not in strings:
        strings[s] = String(s)
      else:
        strings[s].occ += 1

  score = -1
  for string in strings.itervalues():
    if string.score() > score and "'" not in string.s:
      best = string
      score = string.score()
  return best

def get_alnum(program):
  let = [chr(l) for l in range(ord('A'),ord('Z')+1)]
  let += [chr(l) for l in range(ord('a'),ord('z')+1)]
  let += [str(l) for l in range(0,10)]
  letprog = [l for l in let if l in program]
  sys.stderr.write('alphanumerics in the program : %s\n' % ''.join(letprog))
#  for l in letprog: sys.stderr.write("%s %2d\n" % (l, program.count(l)))
  let = [l for l in let if l not in letprog]
  sys.stderr.write('%d alphanumerics left        : %s\n\n' % (len(let), ''.join(let)))
#  return let[random.randint(0,len(let)-1)] if len(let)>0 else None
  return let[0] if len(let)>0 else None

def replace_vars(f, names):
  for old, new in names.iteritems():
    f = f.replace(old, new)
  return f  

def apply_formatting(f, formatting):
  for regex, repl in formatting.iteritems():
    f = re.sub(regex,repl,f)
  return f  

def replace_strings(f):
  global sub
  repl = ''
  sub=[]
#  for i in range(len(alnum)):
  c = get_alnum(f)
  i = 0
  while c:
    i+=1
    string = analyze(f)
    sys.stderr.write('%2d * "%s" -> %s\n' % (string.occ, str(string.s), c))
    f = f.replace(string.s,c)
    sub.append((c,string.s))
    repl = "_%s%s" % (c,string.s) + repl
    c = get_alnum(f)
  return f+repl

names = {
 # functions
 'mark'  :'m',
 'onmove':'o',
 # variables
 'board' :'B',
 'marked':'M',
 'score' :'S',
 'context':'X',
 'numMarked':'N',
 'left'  :'L',
 'mousep':'P',
 'end'   :'E',
 'canvas':'C',
 'offset':'O',
 'delta' :'D'
}

formattings = {
 '//.*?\n'  :'',
 '[ ]*\{\s*':'{',
 '\s*\}'    :'}',
 '\s*=\s*'  :'=',
 '\s*\+=\s*':'+=',
 '\s*\-=\s*':'-=',
 '\s*\?\s*' :'?',
 '\s*>>\s*' :'>>',
 '\s*<<\s*' :'<<',
 '\s*\;\s*' :';',
 '\s*,\s*'  :',',
 '\s*&&\s*' :'&&',
 '\s*\|\|\s*':'||',
 '\)[ ]'    :')',
 'do\s*for':'do for'
}


f = open(sys.argv[1]).read()

sys.stderr.write('input size                   : %d\n' % len(f))
f = replace_vars(f, names)
sys.stderr.write('size with short var names    : %d\n' % len(f))
with open('same.pre.js','w') as g:
  g.write(f)
f = apply_formatting(f, formattings)
f = re.sub(r'\s*\n\s*','',f)
sys.stderr.write('size after formatting        : %d\n' % len(f))

if False:
  f = '\\"%s\\"' % f

  sys.stderr.write('Replacing...\n')
  f = replace_strings(f)
  f = '''eval("eval(%s)".replace(/_(\\w)([^_]*)(?!$)/g,".replace(/$1/g,'$2')"))''' % f
  sys.stderr.write('%s\n' % sub)
  sys.stderr.write('replacements                 : %d\n' % len(sub))
  sys.stderr.write('size after compression       : %d\n' % len(f))

print f

