#!/usr/bin/env python2.5

import cgi
import codecs
import os
import pprint
import shutil
import sys
import sqlite3

SCREENS = 0
COLUMNS = 4
ROWS = 4
HOTSEAT_SIZE = 4
CELL_SIZE = 110

CONTAINER_DESKTOP = -100
CONTAINER_HOTSEAT = -101

DIR = "db_files"
AUTO_FILE = DIR + "/launcher.db"
INDEX_FILE = DIR + "/index.html"

def usage():
  print "usage: print_db.py launcher.db <sw600|sw720> -- prints a launcher.db"
  print "usage: print_db.py <sw600|sw720> -- adb pulls a launcher.db from a device"
  print "       and prints it"
  print
  print "The dump will be created in a directory called db_files in cwd."
  print "This script will delete any db_files directory you have now"


def make_dir():
  shutil.rmtree(DIR, True)
  os.makedirs(DIR)

def adb_root_remount():
  os.system("adb root")
  os.system("adb remount")

def pull_file(fn):
  print "pull_file: " + fn
  rv = os.system("adb pull"
    + " /data/data/com.google.android.googlequicksearchbox/databases/launcher.db"
    + " " + fn);
  if rv != 0:
    print "adb pull failed"
    sys.exit(1)

def get_favorites(conn):
  c = conn.cursor()
  c.execute("SELECT * FROM favorites")
  columns = [d[0] for d in c.description]
  rows = []
  for row in c:
    rows.append(row)
  return columns,rows

def get_screens(conn):
  c = conn.cursor()
  c.execute("SELECT * FROM workspaceScreens")
  columns = [d[0] for d in c.description]
  rows = []
  for row in c:
    rows.append(row)
  return columns,rows

def print_intent(out, id, i, cell):
  if cell:
    out.write("""<span class="intent" title="%s">shortcut</span>""" % (
        cgi.escape(cell, True)
      ))


def print_icon(out, id, i, cell):
  if cell:
    icon_fn = "icon_%d.png" % id
    out.write("""<img style="width: 3em; height: 3em;" src="%s">""" % ( icon_fn ))
    f = file(DIR + "/" + icon_fn, "w")
    f.write(cell)
    f.close()

def print_icon_type(out, id, i, cell):
  if cell == 0:
    out.write("Application (%d)" % cell)
  elif cell == 1:
    out.write("Shortcut (%d)" % cell)
  elif cell == 2:
    out.write("Folder (%d)" % cell)
  elif cell == 4:
    out.write("Widget (%d)" % cell)
  elif cell:
    out.write("%d" % cell)

def print_cell(out, id, i, cell):
  if not cell is None:
    out.write(cgi.escape(unicode(cell)))

FUNCTIONS = {
  "intent": print_intent,
  "icon": print_icon,
  "iconType": print_icon_type
}

def render_cell_info(out, cell, occupied):
  if cell is None:
    out.write("    <td width=%d height=%d></td>\n" %
        (CELL_SIZE, CELL_SIZE))
  elif cell == occupied:
    pass
  else:
    cellX = cell["cellX"]
    cellY = cell["cellY"]
    spanX = cell["spanX"]
    spanY = cell["spanY"]
    intent = cell["intent"]
    if intent:
      title = "title=\"%s\"" % cgi.escape(cell["intent"], True)
    else:
      title = ""
    out.write(("    <td colspan=%d rowspan=%d width=%d height=%d"
        + " bgcolor=#dddddd align=center valign=middle %s>") % (
          spanX, spanY,
          (CELL_SIZE*spanX), (CELL_SIZE*spanY),
          title))
    itemType = cell["itemType"]
    if itemType == 0:
      out.write("""<img style="width: 4em; height: 4em;" src="icon_%d.png">\n""" % ( cell["_id"] ))
      out.write("<br/>\n")
      out.write(cgi.escape(cell["title"]) + " <br/><i>(app)</i>")
    elif itemType == 1:
      out.write("""<img style="width: 4em; height: 4em;" src="icon_%d.png">\n""" % ( cell["_id"] ))
      out.write("<br/>\n")
      out.write(cgi.escape(cell["title"]) + " <br/><i>(shortcut)</i>")
    elif itemType == 2:
      out.write("""<i>folder</i>""")
    elif itemType == 4:
      out.write("<i>widget %d</i><br/>\n" % cell["appWidgetId"])
    else:
      out.write("<b>unknown type: %d</b>" % itemType)
    out.write("</td>\n")

def render_screen_info(out, screen):
  out.write("<tr>")
  out.write("<td>%s</td>" % (screen["_id"]))
  out.write("<td>%s</td>" % (screen["screenRank"]))
  out.write("</tr>")

def process_file(fn):
  global SCREENS, COLUMNS, ROWS, HOTSEAT_SIZE
  print "process_file: " + fn
  conn = sqlite3.connect(fn)
  columns,rows = get_favorites(conn)
  screenCols, screenRows = get_screens(conn)

  data = [dict(zip(columns,row)) for row in rows]
  screenData = [dict(zip(screenCols, screenRow)) for screenRow in screenRows]

  # Calculate the proper number of screens, columns, and rows in this db
  screensIdMap = []
  hotseatIdMap = []
  HOTSEAT_SIZE = 0
  for d in data:
    if d["spanX"] is None:
      d["spanX"] = 1
    if d["spanY"] is None:
      d["spanY"] = 1
    if d["container"] == CONTAINER_DESKTOP:
      if d["screen"] not in screensIdMap:
        screensIdMap.append(d["screen"])
      COLUMNS = max(COLUMNS, d["cellX"] + d["spanX"])
      ROWS = max(ROWS, d["cellX"] + d["spanX"])
    elif d["container"] == CONTAINER_HOTSEAT:
      hotseatIdMap.append(d["screen"])
      HOTSEAT_SIZE = max(HOTSEAT_SIZE, d["screen"] + 1)
  SCREENS = len(screensIdMap)

  out = codecs.open(INDEX_FILE, encoding="utf-8", mode="w")
  out.write("""<html>
<head>
<style type="text/css">
.intent {
  font-style: italic;
}
</style>
</head>
<body>
""")

  # Data table
  out.write("<b>Favorites table</b><br/>\n")
  out.write("""<html>
<table border=1 cellspacing=0 cellpadding=4>
<tr>
""")
  print_functions = []
  for col in columns:
    print_functions.append(FUNCTIONS.get(col, print_cell))
  for i in range(0,len(columns)):
    col = columns[i]
    out.write("""  <th>%s</th>
""" % ( col ))
  out.write("""
</tr>
""")

  for row in rows:
    out.write("""<tr>
""")
    for i in range(0,len(row)):
      cell = row[i]
      # row[0] is always _id
      out.write("""  <td>""")
      print_functions[i](out, row[0], row, cell)
      out.write("""</td>
""")
    out.write("""</tr>
""")
  out.write("""</table>
""")

  # Screens
  out.write("<br/><b>Screens</b><br/>\n")
  out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
  out.write("<tr><td>Screen ID</td><td>Rank</td></tr>\n")
  for screen in screenData:
    render_screen_info(out, screen)
  out.write("</table>\n")

  # Hotseat
  hotseat = []
  for i in range(0, HOTSEAT_SIZE):
    hotseat.append(None)
  for row in data:
    if row["container"] != CONTAINER_HOTSEAT:
      continue
    screen = row["screen"]
    hotseat[screen] = row
  out.write("<br/><b>Hotseat</b><br/>\n")
  out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
  for cell in hotseat:
    render_cell_info(out, cell, None)
  out.write("</table>\n")

  # Pages
  screens = []
  for i in range(0,SCREENS):
    screen = []
    for j in range(0,ROWS):
      m = []
      for k in range(0,COLUMNS):
        m.append(None)
      screen.append(m)
    screens.append(screen)
  occupied = "occupied"
  for row in data:
    # desktop
    if row["container"] != CONTAINER_DESKTOP:
      continue
    screen = screens[screensIdMap.index(row["screen"])]
    cellX = row["cellX"]
    cellY = row["cellY"]
    spanX = row["spanX"]
    spanY = row["spanY"]
    for j in range(cellY, cellY+spanY):
      for k in range(cellX, cellX+spanX):
        screen[j][k] = occupied
    screen[cellY][cellX] = row
  i=0
  for screen in screens:
    out.write("<br/><b>Screen %d</b><br/>\n" % i)
    out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
    for m in screen:
      out.write("  <tr>\n")
      for cell in m:
        render_cell_info(out, cell, occupied)
      out.write("</tr>\n")
    out.write("</table>\n")
    i=i+1

  out.write("""
</body>
</html>
""")

  out.close()

def updateDeviceClassConstants(str):
  global SCREENS, COLUMNS, ROWS, HOTSEAT_SIZE
  devClass = str.lower()
  if devClass == "sw600":
    COLUMNS = 6
    ROWS = 6
    HOTSEAT_SIZE = 6
    return True
  elif devClass == "sw720":
    COLUMNS = 8
    ROWS = 6
    HOTSEAT_SIZE = 8
    return True
  return False

def main(argv):
  if len(argv) == 1 or (len(argv) == 2 and updateDeviceClassConstants(argv[1])):
    make_dir()
    adb_root_remount()
    pull_file(AUTO_FILE)
    process_file(AUTO_FILE)
  elif len(argv) == 2 or (len(argv) == 3 and updateDeviceClassConstants(argv[2])):
    make_dir()
    process_file(argv[1])
  else:
    usage()

if __name__=="__main__":
  main(sys.argv)
