#!/usr/bin/python
# 3D MRI - Converts a series of slices into a 3D grid of voxels.
# Render a series of slices on other axies.
# Copyright (C) November 2007 Neil Fraser
# http://neil.fraser.name/

# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General
# Public License as published by the Free Software Foundation.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# http://www.gnu.org/

import sys
import os
import file_lib

#if len(sys.argv) != 2:
#  print "Usage: %s <source datafile>" % sys.argv[0]
#  sys.exit()
#
#datapath = sys.argv[1]
datapath = "src-neil/data.txt"
a = file_lib.load_data("", datapath)
(x, y, z) = file_lib.get_xyz(a)

colours = []
# Each element contains the number of pixels of that colour, and the colour index.
for b in xrange(256):
  colours.append([0, b])

print "Scanning data (%d x %d x %d) into %d-colour palette" % (x, y, z, len(colours))
for k in xrange(z):
  sys.stdout.write(".")
  sys.stdout.flush()
  for j in xrange(y):
    for i in xrange(x):
      pixel = int(a[k][j][i] * (len(colours) - 1) + 0.5)
      colours[pixel][0] += 1
print "Done.\n"

# Sort the colours by frequency (the first element of each item).
# Least frequent first.
colours.sort()

chars = []
# Each element contains the length of the escaped character, the escaped character and the ascii index.
for b in xrange(256):
  char = chr(b)
  # Don't use \0 shortcut for char zero, since \000 is ambiguous:
  # '\0' + '00' [length 3] vs '\000' [length 1]
  if char == '\b':
    char = '\\b'
  elif char == '\t':
    char = '\\t'
  elif char == '\n':
    char = '\\n'
  elif char == '\v':
    char = '\\v'
  elif char == '\f':
    char = '\\f'
  elif char == '\r':
    char = '\\r'
  elif char == '"':
    char = '\\"'
  elif char == '\\':
    char = '\\\\'
  elif char < ' ' or char > '~':
    # Convert to \xXX format
    pyhex = hex(b)
    if b < 16:
      char = "\\x0%s" % (pyhex[-1])
    else:
      char = "\\x%s%s" % (pyhex[-2], pyhex[-1])
  chars.append((len(char), char, b))

# Sort the chars by the length (the first element of each item).
# Largest length first.
chars.sort()
chars.reverse()

colour2char = range(256)
# Create a lookup table from colours to escaped characters.
for b in xrange(256):
  colour2char[colours[b][1]] = chars[b][1]

index2colour = range(256)
# Create a lookup table from ascii index to colour.
for b in xrange(256):
  index2colour[chars[b][2]] = colours[b][1]

  #print "%d: [%d, %d]" % (b, chars[b][0], chars[b][1])
  #print "%d: [%d, %d]" % (b, palette[b][0], palette[b][1])

jsfile = "data.js"
print "Writing %s" % jsfile

f = open(jsfile, "w")

f.write("palette=[")
for i in xrange(len(index2colour)):
  if i != 0:
    f.write(",")
  colour = index2colour[i]
  f.write("[%d,%d,%d]" % (colour, colour, colour))
f.write("];\n")


f.write("grid=[")
for k in xrange(z):
  sys.stdout.write(".")
  sys.stdout.flush()
  if k != 0:
    f.write(",\n\n")
  f.write("[")
  for j in xrange(y):
    if j != 0:
      f.write(",\n")
    f.write('"')
    for i in xrange(x):
      colour = a[k][j][i]
      colour = int(colour * 255 + 0.5)
      char = colour2char[colour]
      f.write(char)
    f.write('"')
  f.write("]")
f.write("];\n")

f.close()
print "Done.\n"
