#!/usr/bin/python
# vim: set ts=2 expandtab:
"""
Module: ocr
Desc:
Author: John O'Neil
Email: oneil.john@gmail.com
DATE: Saturday, August 25th 2013

  Front to back end Manga text detection.
  Input is image file of raw manga image
  Output is HTML page annotating image with detected text.
  
"""
#import clean_page as clean
import connected_components as cc
import run_length_smoothing as rls
import clean_page as clean
import ocr
import segmentation as seg
import furigana
import arg
import defaults

import numpy as np
import cv2
import sys
import argparse
import os
import scipy.ndimage
import datetime


if __name__ == '__main__':

  proc_start_time = datetime.datetime.now()

  parser = arg.parser
  parser = argparse.ArgumentParser(description='Generate HTML annotation for raw manga scan with detected OCR\'d text.')
  parser.add_argument('infile', help='Input (color) raw Manga scan image to annoate.')
  parser.add_argument('-o','--output', dest='outfile', help='Output html file.')
  parser.add_argument('-v','--verbose', help='Verbose operation. Print status messages during processing', action="store_true")
  parser.add_argument('--display', help='Display output using OPENCV api and block program exit.', action="store_true")
  parser.add_argument('--furigana', help='Attempt to suppress furigana characters which interfere with OCR.', action="store_true")
  #parser.add_argument('-d','--debug', help='Overlay input image into output.', action="store_true")
  #parser.add_argument('--sigma', help='Std Dev of gaussian preprocesing filter.',type=float,default=None)
  parser.add_argument('--binary_threshold', help='Binarization threshold value from 0 to 255.',type=int,default=defaults.BINARY_THRESHOLD)
  #parser.add_argument('--segment_threshold', help='Threshold for nonzero pixels to separete vert/horiz text lines.',type=int,default=1)
  arg.value = parser.parse_args()

  infile = arg.string_value('infile')
  outfile = arg.string_value('outfile',default_value=infile + '.html')

  if not os.path.isfile(infile):
    print 'Please provide a regular existing input file. Use -h option for help.'
    sys.exit(-1)
  img = cv2.imread(infile)
  gray = clean.grayscale(img)

  binary_threshold=arg.integer_value('binary_threshold',default_value=defaults.BINARY_THRESHOLD)
  if arg.boolean_value('verbose'):
    print 'Binarizing with threshold value of ' + str(binary_threshold)
  inv_binary = cv2.bitwise_not(clean.binarize(gray, threshold=binary_threshold))
  binary = clean.binarize(gray, threshold=binary_threshold)

  segmented_image = seg.segment_image(gray)
  segmented_image = segmented_image[:,:,2]
  segmentation_mask = np.array(segmented_image!=0,'B')
  cleaned = cv2.bitwise_not(binary*segmentation_mask)

  if arg.boolean_value('furigana'):
    if arg.boolean_value('verbose'):
      print 'Attempting to suppress furigana'
    furigana_areas = furigana.estimate_furigana(gray,segmented_image)
    furigana_mask = np.array(furigana_areas==0,'B')
    cleaned = cv2.bitwise_not(cv2.bitwise_not(cleaned)*furigana_mask)

  #text columns are in the 3rd channel
  #columns = segmented_image[:,:,2]
  components = cc.get_connected_components(segmented_image)

  #perhaps do more strict filtering of connected components because sections of characters
  #will not be dropped from run length smoothed areas? Yes. Results quite good.
  #filtered = cc.filter_by_size(img,components,average_size*100,average_size*1)

  #Build html page with image
  from django.template import Template, Context
  from django.conf import settings
  from django.template.loader import render_to_string
  settings.configure()
  blurbs = ocr.ocr_on_bounding_boxes(cleaned, components)

  proc_stop_time = datetime.datetime.now()
  processing_time = proc_stop_time - proc_start_time

  template = u'''
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>{{ image }}</title>
    <link type="text/css" rel="stylesheet" href="annotorious.css" />
    <script type="text/javascript" src="annotorious.min.js"></script>
    <script>
      //anno.addPlugin('ExamplePlugin', {});

      
    </script>  
  </head>
  <body>
    <h1>{{ image }}.</h1>
    <p>Page rendered on {% now "r" %} in {{ processing_time }} seconds</p>
    <table>
      <tr valign="top">
        <td>
          <img src="{{ image }}" alt="{{ image }}" class="annotatable" id="manga_page"/>
        </td>
        <td width="500">
          <table>
              {% for blurb in blurbs %}
              <tr>
              {{ blurb.confidence }}%: {{ blurb.text|linebreaksbr }}<br>
              </tr>
              {% endfor %}
          <table>
        </td>
      </tr>
    </table> 
<script>
      function AddBlurb(image, X, Y, W, H, blurb)
      {
        var annotation = {
          //image URL
          src : document.getElementById('manga_page').src,
          text : blurb,

          shapes : [{
          type : 'rect',
          units: 'pixel',
          geometry : { x : X, y: Y, width : W, height: H }

          //editable : false
          }]
          }
        anno.addAnnotation(annotation);//, opt_replace);
      }

      window.onload = function() {
        {% for blurb in blurbs %}
        AddBlurb( "{{ image }}", {{ blurb.x }}, {{ blurb.y }}, {{ blurb.w }}, {{ blurb.h }}, "{{ blurb.text|linebreaksbr }}" );
        {% endfor %}
      }

    </script>
  </body>
  </html>
  '''

  t = Template(template)
  c = Context({"image": infile,
              "blurbs":blurbs,
              "processing_time":processing_time.total_seconds()})
  #print t.render(c)
  #for blurb in blurbs:
  #  print str(blurb.confidence)+'% :'+ blurb.text
  #open(outfile, "w").write(render_to_string(template, c))
  open(outfile, "w").write(t.render(c).encode("utf-8"))
  
  
  if arg.boolean_value('display'):
    cv2.imshow('img',img)
    #cv2.imwrite('segmented.png',img)
    cv2.imshow('run_length_smoothed_or',run_length_smoothed_or)
    #cv2.imwrite('run_length_smoothed.png',run_length_smoothed_or)
    #cv2.imwrite('cleaned.png',cleaned)

    if cv2.waitKey(0) == 27:
      cv2.destroyAllWindows()
    cv2.destroyAllWindows()
