# -*- coding: utf-8 -*-

###########################################################################
#    OCRFeeder - The complete OCR suite
#    Copyright (C) 2009-2013 Joaquim Rocha
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    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.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
###########################################################################

from boxesarea import BoxesArea
from dataHolder import DataBox, PageData, TEXT_TYPE, IMAGE_TYPE
from ocrfeeder.feeder.documentGeneration import OdtGenerator, HtmlGenerator, PlaintextGenerator, PdfGenerator
from ocrfeeder.feeder.imageManipulation import *
from ocrfeeder.feeder.layoutAnalysis import *
from project import ProjectSaver, ProjectLoader
from ocrfeeder.util import graphics, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, \
     ALIGN_FILL, PAPER_SIZES
from ocrfeeder.util.lib import debug, getNonExistingFileName, unpaperImage
from ocrfeeder.util.configuration import ConfigurationManager
from ocrfeeder.util import constants
from ocrfeeder.util.asyncworker import AsyncItem
from widgetPresenter import BoxEditor, PagesToExportDialog, FileDialog, \
    PageSizeDialog, UnpaperDialog, \
    QueuedEventsProgressDialog, SpellCheckerDialog
import gettext
from gi.repository import Gtk, GObject, Gdk, GdkPixbuf, Pango
import math
import os.path
import threading
import sys
_ = gettext.gettext

class ImageReviewer(Gtk.HPaned):

    def __init__(self, main_window, page_data, ocr_engines):
        super(ImageReviewer, self).__init__()
        self.configuration_manager = ConfigurationManager()
        self.main_window = main_window
        self.path_to_image = page_data.image_path
        self.text_box_fill_color = (94, 156, 235, 150)
        self.box_stroke_color = (94, 156, 235, 250)
        self.image_box_fill_color = (0, 183, 0, 150)
        self.selectable_boxes_area = BoxesArea(self.path_to_image)
        self.selectable_boxes_area.connect('selected_box', self.selectedBox)
        self.selectable_boxes_area.connect('removed_box', self.removedBox)
        self.selectable_boxes_area.connect('updated_box', self.updatedBox)
        self.selectable_boxes_area.connect('dragged_box', self.updatedBoxBounds)
        self.selectable_boxes_area.connect('deselected_box',
                                           self.deselectedBoxCb)
        self.image_pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.path_to_image)
        self.set_position(500)
        self.show()
        self.ocr_engines = ocr_engines
        self.editor = Editor(self.image_pixbuf, self.ocr_engines, self)
        self.boxes_dict = {}

        selectable_boxes_scrolled_window = Gtk.ScrolledWindow()
        selectable_boxes_scrolled_window.get_accessible().set_name(
                                                         _('Selectable areas'))
        selectable_boxes_scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        selectable_boxes_scrolled_window.add(self.selectable_boxes_area)
        self.selectable_boxes_area.show()
        selectable_boxes_scrolled_window.show()

        self.pack1(selectable_boxes_scrolled_window, True, False)
        self.pack2(self.editor.box_editor, True, False)
        self.page = page_data
        self.updatePageData(self.page)
        selectable_boxes_scrolled_window.connect_after("size-allocate", self.zoomFitCb)

    def setTextFillColor(self, color):
        self.text_box_fill_color = color
        self.selectable_boxes_area.setAreaFillRgba(self.text_box_fill_color)

    def setBoxesStrokeColor(self, color):
        self.box_stroke_color = color
        self.selectable_boxes_area.setAreaStrokeRgba(self.box_stroke_color)

    def setImageFillColor(self, color):
        self.image_box_fill_color = color

    def addBoxEditor(self, box, data_box = None):
        if not data_box:
            data_box = DataBox()
            data_box.setLanguage(self.configuration_manager.language)
            data_box.updateBoundsFromBox(box)
        self.boxes_dict[box] = data_box
        self.editor.setBoxes(box, data_box)

    def selectedBox(self, widget, box):
        data_box = self.boxes_dict.get(box)
        if data_box:
            self.editor.setBoxes(box, data_box)
        else:
            self.addBoxEditor(box)
        self.updateMainWindow()

    def deselectedBoxCb(self, widget, box):
        self.updateMainWindow()

    def updatedBox(self, widget, box):
        if self.editor.box == box:
            self.editor.update(box)

    def updatedBoxBounds(self, widget, box):
        if self.editor.box == box:
            self.editor.data_box.updateBoundsFromBox(box)

    def removedBox(self, widget, box):
        self.updateMainWindow()
        if not self.boxes_dict.has_key(box):
            return False
        del self.boxes_dict[box]
        if self.editor.box == box:
            self.editor.updateDataBox(None)
            self.editor.box = None
        self.selectable_boxes_area.selectNextArea()
        return False

    def clear(self):
        self.selectable_boxes_area.clearAreas()
        self.editor.updateDataBox(None)
        self.editor.box = None
        self.boxes_dict.clear()

    def applyTextColors(self):
        self.selectable_boxes_area.fill_color_rgba = self.text_box_fill_color
        self.selectable_boxes_area.stroke_color_rgba = self.box_stroke_color

    def applyImageColors(self):
        self.selectable_boxes_area.fill_color_rgba = self.image_box_fill_color
        self.selectable_boxes_area.stroke_color_rgba = self.box_stroke_color

    def addNewEditorsToAllBoxes(self):
        self.editor_list = []
        boxes = self.selectable_boxes_area.getAllAreas()
        for box in boxes:
            self.addBoxEditor(box)

    def performOcrForSelectedBoxes(self):
        selected_boxes = self.selectable_boxes_area.getSelectedAreas()
        configured_engine = None
        for engine, path in self.ocr_engines:
            if engine.name == self.configuration_manager.favorite_engine:
                configured_engine = engine
                break
        if not configured_engine:
            return
        for box in selected_boxes:
            data_box = self.boxes_dict[box]
            self.performOcrForDataBox(data_box, engine)
        self.editor.updateDataBox(self.editor.data_box)
        self.updateMainWindow()

    def performOcrForDataBox(self, data_box, engine):
        if engine.hasLanguages():
            engine.setLanguage(data_box.getLanguage())
        pixbuf_width = self.image_pixbuf.get_width()
        pixbuf_height = self.image_pixbuf.get_height()
        new_pixbuf_width = min(data_box.getWidth(), pixbuf_width)
        new_pixbuf_height = min(data_box.getHeight(), pixbuf_height)
        subpixbuf = self.image_pixbuf.new_subpixbuf(data_box.getX(),
                                             
       data_box.getY(),
                                                    new_pixbuf_width,
                                                    new_pixbuf_height)
        subpixbuf.x = data_box.getX()
        subpixbuf.y = data_box.getY()
        subpixbuf.width = pixbuf_width
        image = graphics.convertPixbufToImage(subpixbuf)
        layout_analysis = LayoutAnalysis(engine,
         
                                clean_text = self.configuration_manager.clean_text)
        text = layout_analysis.readImage(image)
        data_box.setText(text)
        self.main_window.copy_to_clipboard_menu.set_sensitive(True)
        self.main_window.spellchecker_menu.set_sensitive(True)
        debug('Finished reading')
        text_size = layout_analysis.getTextSizeFromImage(image,
              