#!/usr/bin/python
import traceback
import sys, math, os
import copy
from PIL import Image, ImageDraw
import cv2
import numpy as np

#import gui_related

import wx

app = wx.App(False)

#print wx.GetDisplaySize()


lines=[]
filename='noyes2.str'
with open(os.path.join(os.path.dirname(__file__), filename), 'rb') as fl:
    lines=fl.read()

bmp=[]

print 'A5 at: ', lines.index('\xA5')
pixes=[]
pix=[]
class fib_pattern(object):
    def write_as_12_bit(self, lines):
        #fl1=open('out.txt1', 'wb')
        i=lines.index('\xd7') - 3
        firstTime=True
        size = (4096, 4096)             # size of the image to create
        im = Image.new('L', size) # create the image, 'L' for greyscale
        self.maxX=0
        self.maxY=0
        self.minY=4096
        self.minX=4096
        while True:
            try:    
                b1 = ord(lines[i])
                b2 = ord(lines[i+1])
                b3 = ord(lines[i+2])
                b4 = ord(lines[i+3])

                #something to do with how nybble order gets packed by C compilers
                nib1 = b2 >> 4
                nib2 = b2 & 0xF
                x = b1 | (nib2<<8)
                y = (b3<<4) | nib1

                dwell = b4

                #keep some statistics
                if x>self.maxX:
                    self.maxX=x
                if y>self.maxY:
                    self.maxY=y
                if x<self.minX:
                    self.minX=x
                if y<self.minY:
                    self.minY=y

                #write the pixel to the image
                im.putpixel((x,y), dwell)

                #advance by 4 bytes
                i+=4
                
            except IndexError:
                break
        im.save('out_test1.png', 'PNG')
        print "maxX %d, maxY %d" % (self.maxX, self.maxY)
        print "minX %d, minY %d" % (self.minX, self.minY)
        print 'num pixels: %d' % (i/4)
        self.numPixels = (i/4)

    def write_as_video(self, lines):
        #fl1=open('out.txt1', 'wb')
        i=lines.index('\xd7') - 3
        print 'i', i 
        firstTime=True
        size = (4096, 4096)             # size of the image to create
        #im = Image.new('L', size) # create the image, 'L' for greyscale
        
        width = (self.maxX - self.minX) + 1
        height = (self.maxY - self.minY) + 1

        print 'width %d height %d maxX %d minX %d maxY %d minY %d' % (width, height, self.maxX, self.minX, self.maxY, self.minY)

        #out = cv2.VideoWriter('output.avi',cv2.cv.CV_FOURCC('D', 'I', 'V', 'X'), 20.0, (width,height))
        #fourcc = cv2.cv.CV_FOURCC('m', 'p', '4', 'v') # note the lower case
        #fourcc =  cv2.cv.CV_FOURCC('M','J','P','G')
        #fourcc = cv2.cv.CV_FOURCC('m', 'p', '4', '2')
        #fourcc = cv2.cv.CV_FOURCC('i','Y','U', 'V')#'D','I','V','X')  #CAP_PROP
        #fourcc = cv2.cv.CV_FOURCC(*'XVID')
        #print fourcc
        #out = cv2.VideoWriter()
        #success = out.open('output.avi',0,30,( width, height),True)
        m = max(width, height)
        #out = cv2.VideoWriter("test.avi", cv2.cv.CV_FOURCC('i','Y','u','v'), #'F', 'M', 'P', '4'),'H', '2', '6', '4'
        #                                    30, (width, height), False)  #import cv syntax CreateVideoWriter
        #out = cv2.VideoWriter("testmp42.mp4", cv2.cv.CV_FOURCC('M','P','4','2'), #'F', 'M', 'P', '4'),'H', '2', '6', '4'     'D','I','V','3' (works oks)
        #                                    90, (width, height), False) #'X','2','6','4'    width, height   
        #out = cv2.VideoWriter("testmp4.avi", cv2.cv.CV_FOURCC('D','I','V','3'), 30, (width, height), True)
        #out = cv2.VideoWriter("test_x264.avi", cv2.cv.CV_FOURCC('X','2','6','4'), 30, (width, height), True)
        #print 'video opened? %s' % out.isOpened()
        #print success
        blank_image = np.zeros((width, height,1), np.uint8)
        #blank_image = cv2.cv.CreateImage((m, m), 8, 1)
        #cv_image = cv2.cv.CreateImage((height, width), cv2.IPL_DEPTH_8U,1)
        cv2.namedWindow('FIB pattern raster sequence')#, cv2.CV_WINDOW_NORMAL|cv2.CV_WINDOW_KEEPRATIO | cv2.CV_GUI_EXPANDED)
        lastKey=0 
        #available_screen_size = gui_related.get_available_screen_size()
        
        topBarHeight, sideBarWidth, widthAvailable, heightAvailable = wx.ClientDisplayRect()
        heightAvailable -= topBarHeight # account for the highGui window's title bar

        if width > widthAvailable:
            scaleWidth=float(widthAvailable)/width
        else:
            scaleWidth = 1
        if height > heightAvailable:
            scaleHeight = float(heightAvailable)/height
        else:
            scaleHeight = 1
        scale = min(scaleWidth, scaleHeight)
        scaled_frame_size = (int(width*scale), int(height*scale))

        while True:
            try: 

                b1 = ord(lines[i])
                b2 = ord(lines[i+1])
                b3 = ord(lines[i+2])
                b4 = ord(lines[i+3])

                #something to do with how nybble order gets packed by C compilers
                nib1 = b2 >> 4
                nib2 = b2 & 0xF
                x = b1 | (nib2<<8)
                y = (b3<<4) | nib1

                dwell = b4


                #write the pixel to the image
                #im.putpixel((x,y), dwell)
                blank_image[(y-self.minY, x-self.minX)] = dwell
                
                #cv2.SetReal2D(blank_image, x-self.minX,y-self.minY, dwell)

                
                
                #cv2.cv.WriteFrame(out, 
                #im = cv2.cv.fromarray(blank_image)
                
                #cv2.Set2D(cv_image, x, y, dwell)
                #advance by 4 bytes
                i+=4
                if i%256==0:
                    pass
                    #out.write(cv2.cvtColor(blank_image,cv2.COLOR_GRAY2RGB))
                    #out.write(blank_image)
                    #cv2.WriteFrame(out, blank_image)
                    #blank_image = cv.CreateImage((width, height), 8, 1)
                    #cv2.SetZero(blank_image)

                    #cv2.imshow('img1',blank_image) 
                    #cv2.waitKey(30)                 # Waits forever for user to press any key
                    #print 'frame'
                    #blank_image = np.zeros((width,height,1), np.uint8)
                
                if (i/4%(self.numPixels/100)==1):
                    print 'percent done: %d' % (float(i/4) / self.numPixels *100)
                    if not lastKey == 27:
                        cv2.imshow('FIB pattern raster sequence',cv2.resize(blank_image, scaled_frame_size) )
                    lastKey = cv2.waitKey(30)                 # Waits forever for user to press any key
                    print i/4, self.numPixels
                
            except IndexError:
                print "IndexError, last tuple started at byte: %d " % (i - 4)
                #traceback.print_exc()
                #out.write(blank_image)
                #out.write(cv2.cvtColor(blank_image,cv2.COLOR_GRAY2RGB))
                #out.write(blank_image)
                #cv2.waitKey(30)

                break
        #im.save('out_test1.png', 'PNG')
        #out.release()
        #out=None
        print "maxX %d, maxY %d" % (self.maxX, self.maxY)
        print "minX %d, minY %d" % (self.minX, self.minY)
        print 'num pixels: %d' % (i/4)
        while cv2.waitKey(0) != 27:
            cv2.imshow('FIB pattern raster sequence',cv2.resize(blank_image, scaled_frame_size) )
        
        cv2.destroyAllWindows() 

def write_image(img):
    w = max([p[0] for p in img])
    h = max([p[1] for p in img])

    size = (4096, 4096)             # size of the image to create
    im = Image.new('L', size) # create the image
    draw = ImageDraw.Draw(im)   # create a drawing object that is
                                # used to draw on the new image
    red = (255,0,0)    # color of our text
    table = sum(zip(*img), ())
    #draw.point(img)
    im.putdata(table)

    """
    #fff7fb
    #ece7f2
    #d0d1e6
    #a6bddb
    #74a9cf
    #3690c0
    #0570b0
    #034e7b
    """

    del draw # I'm done drawing so I don't need this anymore
    im.save('out_test1.png', 'PNG')

pat = fib_pattern()
pat.write_as_12_bit(copy.deepcopy(lines))
pat.write_as_video(lines)
#write_as_byte_w_offset(lines)
#write_image(pixes)

sys.exit(1)

pixels = []
pix=[0,0,0]

"""
for i in range(0, len(lines), 2):
    #num = int(lines[i].encode('hex'), 16)
    num = struct.unpack( "H", lines[i:i+2] )
    sys.stdout.write(str(num))
    pix[i%3]=num
    if i%3 ==2:
        print ''
        pixels.append((pix[0], pix[1], pix[2]))
    else:
        sys.stdout.write(', ')

    #print c, '\t %s' % lines[i]
"""
fl=open(filename, 'rb')
for i in range(0,8):
    fl.read(1)
r = BitReader(fl)
i=0
j=0
while True:
    b1 = fl.read(1)
    b23 = fl.read(1)
    b3_latter = fl.read(1)
    b2 = ord(b23)>>4 & (int('f',16))
    if not i==2:
        x = r.readbits(12)
    else:
        x = r.readbits(8)
    if ( r.read == 0 ):
        break
    pix[i%3]=x
    i+=1
    if i==3:
        
        pixels.append((pix[0], pix[1], pix[2]))
        #print '%s, %s, %s' % (pix[0], pix[1], pix[2])
        i=0
        j+=1
        #if j==50:
        #    break

h = max([p[0] for p in pixels])
w = max([p[1] for p in pixels])
z = max([p[2] for p in pixels])

print 'maxes of h: %s, w: %s, z: %s' %(h, w, z)
import array
pixmap = [array.array('i',(0 for i in range(0,h+1))) for i in range(0,h+1)]

for pixel in pixels:
    pixmap[pixel[0]][pixel[1]] = pixel[2]

pixlist = []
fl1=open('out.raw', 'wb')
for i in range(0, h):
    for j in range(0, w):
        fl1.write(struct.pack('i', pixmap[i][j]))
fl1.close()

fl.close()