#!/usr/bin/env python

# File   : $HeadURL$
# Version: $Id$

import gtk, sys
import numpy as np

from FigureWidget import FigureWidget
from MatrixWidget import MatrixWidget
from Ai import Ai

import common as com

def _draw_line(image, start, end):
    start = np.array(start, dtype=np.int)
    end = np.array(end, dtype=np.int)

    delta = abs(end - start)

    e = delta[0]/2.0
    x, y = start
    image[y, x] = com.FEATURE_RANGE_MAX
    while np.any((x, y) != end):
        if e < 0.0 or x == end[0]:
            y += -1 if start[1] > end[1] else 1
            e += delta[0]
        if e >= 0.0 and x != end[0]:
            x += -1 if start[0] > end[0] else 1
            e -= delta[1]
        image[y, x] = com.FEATURE_RANGE_MAX

def button_go_clicked(button, main_window):
    coords = map(lambda line: com.MATIX_IMAGE_SIZE*line,
                 main_window.figure.get_coords())
    image = np.zeros((com.MATIX_IMAGE_SIZE, com.MATIX_IMAGE_SIZE),
                     dtype=np.float)

    for line in coords:
        for i in range(line.shape[0]-1):
            _draw_line(image, line[i], line[i+1])

    main_window.push_image(image,
                           str(main_window.ai.classify(image))
                           )

    main_window.figure.clear_coords()
    main_window.set_focus(main_window.button_go)

def button_clear_clicked(button, main_window):
    main_window.figure.clear_coords()
    main_window.set_focus(main_window.button_go)

class MainWindow(gtk.Window):
    TITLE = "OCR Demo - Press middle mouse button to classify, right" \
        " mouse button to clear"

    MIN_WIDTH = 800
    MIN_HEIGHT = 260

    MAIN_PADDING = 4
    BOX_PADDING = 4

    MARKUP_PRE = '<span size="x-large" color="red"><b>'
    MARKUP_POST = '</b></span>'

    def __init__(self):
        # Main Window
        gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL)
        self.set_title(self.TITLE)
        self.connect("delete-event", MainWindow.on_delete)
        self.set_size_request(self.MIN_WIDTH, self.MIN_HEIGHT)

        # AI
        self.ai = Ai()
        self.ai.load_classifier()

        # Main Container
        self.main_align = gtk.Alignment(xalign=0.0, yalign=0.0,
                                        xscale=1.0, yscale=1.0)
        self.main_align.set_padding(self.MAIN_PADDING,
                                    self.MAIN_PADDING,
                                    self.MAIN_PADDING,
                                    self.MAIN_PADDING)
        self.add(self.main_align)

        # Figure HBox
        self.figure_hbox = gtk.HBox(homogeneous=False,
                                    spacing=self.BOX_PADDING)
        self.main_align.add(self.figure_hbox)

        # Main VBox
        self.main_vbox = gtk.VBox(homogeneous=False,
                                  spacing=self.BOX_PADDING)
        self.figure_hbox.add(self.main_vbox)


        # Figure
        self.figure = FigureWidget(button_go_clicked, (None, self))
        self.main_vbox.pack_start(self.figure, expand=True, fill=True,
                                  padding=0)

        # VSeperator
        self.figure_vsep = gtk.VSeparator()
        self.figure_hbox.pack_start(self.figure_vsep, expand=False,
                                    fill=True, padding=0)

        # History
        self.mat_table = gtk.Table(rows=com.HISTORY_HEIGHT,
                                   columns=com.HISTORY_WIDTH,
                                   homogeneous=True)
        self.figure_hbox.pack_start(self.mat_table, expand=True,
                                    fill=True, padding=0)

        self.mat_frame = []
        self.mat_vbox = []
        self.mat_images = []
        self.mat_result = []
        for y in range(com.HISTORY_HEIGHT):
            for x in range(com.HISTORY_WIDTH):
                i = y*com.HISTORY_WIDTH + x

                self.mat_frame.append(gtk.Frame(
                        "History " + str(y*com.HISTORY_WIDTH + x)))
                if i == 0:
                    self.mat_frame[i].set_label("Current")
                    mf_style = self.mat_frame[i].get_style()
                    mf_style.bg[gtk.STATE_NORMAL] = com.COLOR_BLUE
                    self.mat_frame[i].set_style(mf_style)
                self.mat_table.attach(self.mat_frame[i],
                                      left_attach=x, right_attach=x+1,
                                      top_attach=y, bottom_attach=y+1,
                                      xpadding=self.BOX_PADDING)

                self.mat_vbox.append(gtk.VBox(homogeneous=False,
                                              spacing=self.BOX_PADDING)
                                     )
                self.mat_frame[i].add(self.mat_vbox[i])

                self.mat_result.append(gtk.Label(
                        self.MARKUP_PRE + "?" + self.MARKUP_POST))
                self.mat_result[i].set_use_markup(True)
                self.mat_vbox[i].pack_start(
                    self.mat_result[i], expand=False, fill=True,
                    padding=0)

                self.mat_images.append(MatrixWidget(
                        com.MATIX_IMAGE_SIZE))
                self.mat_vbox[i].pack_start(
                    self.mat_images[i], expand=True, fill=True,
                    padding=self.BOX_PADDING)

        # HSeperator
        self.main_hsep = gtk.HSeparator()
        self.main_vbox.pack_start(self.main_hsep, expand=False,
                                  fill=True, padding=0)

        # HBox
        self.hbox = gtk.HBox(homogeneous=False,
                             spacing=self.BOX_PADDING)
        self.main_vbox.pack_end(self.hbox, expand=False, fill=True,
                                padding=0)

        # Button Go
        self.button_go = gtk.Button(label="_Classify")
        self.button_go.connect("clicked", button_go_clicked, self)
        self.button_go.set_focus_on_click(False)
        self.hbox.add(self.button_go)

        # Button clear
        self.button_clear = gtk.Button(label="Clea_r")
        self.button_clear.set_focus_on_click(False)
        self.button_clear.connect("clicked", button_clear_clicked,
                                  self)
        self.hbox.add(self.button_clear)

    def on_delete(self, event):
        gtk.Window.destroy(self)
        gtk.main_quit()
        return True

    def push_image(self, image, str):
        prev_image = image
        prev_str = str

        for i in range(com.HISTORY_WIDTH*com.HISTORY_HEIGHT):
            tmp_image = self.mat_images[i].get_image()
            tmp_str = self.mat_result[i].get_text()
            self.mat_images[i].set_image(prev_image)
            self.mat_result[i].set_markup(
                self.MARKUP_PRE + prev_str + self.MARKUP_POST)
            prev_image = tmp_image
            prev_str = tmp_str

def main(argv):
    gtk.gdk.threads_init()

    window = MainWindow()
    window.show_all()
    gtk.main()

if __name__ == '__main__':
    sys.exit(main(sys.argv))
