from text_tree import insert
from treesort import measure_tree
from visualizer import visualize_node
from descriptions import descriptions
from graph_utils import make_name_generator, wrapped
from graphviz import Graph
from random import shuffle
import datetime

import exifread
from PIL import Image

def get_image_date (path):
  f = open(path, 'rb')

  # Return Exif tags
  tags = exifread.process_file(f)
 
  if 'EXIF DateTimeOriginal' in tags.keys():
    return datetime.datetime.strptime(str(tags['EXIF DateTimeOriginal']), '%Y:%m:%d %H:%M:%S')
  elif 'Image DateTime' in tags.keys():
    return datetime.datetime.strptime(str(tags['Image DateTime']), '%Y:%m:%d %H:%M:%S')
  else:
    print('No date for "{}"'.format(path))
    return datetime.datetime.now()


def count_trees (text):
  count = 0
  words = ['tree', 'forest', 'leave', 'branch', 'stump', 'grass', 'nature', 'flower', 'rock', 'mushroom', 'nature', 'plant']
  neg_words = ['computer', 'microphone', 'screen', 'laptop', 'machine', 'pool', 'project', 'text', 'culture', 'board', 'wire', 'chip', 'technology']
  text = text.lower()

  for word in words:
    count += text.count(word)


  for word in neg_words:
    count -= text.count(word)

  return count


def make_tree (values, key = lambda word: word):
  tree = None

  for value in values:
    tree = insert(tree, value, key)

  return tree

def make_image_node(graph, generate_node_name, image):
  node_name = generate_node_name()

  im = Image.open(image[1])
  w, h = im.size

  sw = 4.75 if w < h else 3.75

  graph.node(node_name,
    image=image[1],
    label='',
    shape='box',
    color='transparent',
    width=str(sw*(w/h)),
    height=str(sw),
    imagepos='mc',
    fixedsize='true',
    fillcolor='transparent',
    imagescale='height'
  )

  return node_name

def make_text_node(graph, generate_node_name, image):
  node_name = generate_node_name()
  graph.node(node_name,
    label='<{}<BR align=\'left\'/>>'.format(wrapped(image[0], 35, join="<BR align='left'/>")),
    fontname='Fira Mono',
    fontcolor='black',
    shape='plaintext',
    color='black',
    fontsize='14'
  )
  return node_name


if __name__ == '__main__':
  generate_node_name = make_name_generator(length=3)

  images = [(description, image, color, get_image_date(image)) for image, description, color in descriptions]

  shuffle(images)
  description_tree = make_tree(images, lambda image: count_trees(image[0]))
  date_tree = make_tree(images, lambda image: image[3])
  color_tree = make_tree(images, lambda image: image[2][0])

  while measure_tree(description_tree) > 8 or measure_tree(date_tree) > 9 or measure_tree(color_tree) > 9:
    print(measure_tree(description_tree), measure_tree(date_tree), measure_tree(color_tree))
    shuffle(images)
    description_tree = make_tree(images, lambda image: count_trees(image[0]))
    date_tree = make_tree(images, lambda image: image[3])
    color_tree = make_tree(images, lambda image: image[2][0])


  graph = Graph(name='images_description', format='svg', engine='dot')
  graph.attr('graph', splines='line', rankdir='BT', ranksep='1', nodesep='0.15')
  graph.attr(label="<36 Images, ordered by mentions of nature in their description<BR align='left'/><BR align='left'/>Listen to the descriptions at frart.algoliterarypublishing.net/treesort>", labelloc='b', labeljust='l', fontname='Fira mono', fontsize='14', fontcolor='black')
  visualize_node(graph, make_image_node, generate_node_name, description_tree)
  graph.render('description_images_random')

  graph = Graph(name='descriptions_description', format='svg', engine='dot')
  graph.attr('graph', splines='line', rankdir='BT', ranksep='2', nodesep='0.15', margin='1,1')
  graph.attr(label="<36 Image descriptions, ordered by mentions of nature<BR align='left'/><BR align='left'/>Listen to the descriptions at frart.algoliterarypublishing.net/treesort>", labelloc='b', labeljust='l', fontname='Fira mono', fontsize='14', fontcolor='black', image='qr.gif')
  visualize_node(graph, make_text_node, generate_node_name, description_tree)
  graph.render('description_text_random')

  graph = Graph(name='images_colors', format='svg', engine='dot')
  graph.attr('graph', splines='line', rankdir='BT', ranksep='1')
  graph.attr(label="<36 Images, ordered by dominant color<BR align='left'/><BR align='left'/>Listen to the descriptions at frart.algoliterarypublishing.net/treesort>", labelloc='b', labeljust='l', fontname='Fira mono', fontsize='12', fontcolor='black')
  visualize_node(graph, make_image_node, generate_node_name, color_tree)
  graph.render('images_colors')

  graph = Graph(name='images_dates', format='svg', engine='dot')
  graph.attr('graph', splines='line', rankdir='BT', ranksep='1', nodesep='0.15')
  graph.attr(label="<36 Images, ordered by date<BR align='left'/><BR align='left'/>Listen to the descriptions at frart.algoliterarypublishing.net/treesort>", labelloc='b', labeljust='l', fontname='Fira mono', fontsize='12', fontcolor='black')
  visualize_node(graph, make_image_node, generate_node_name, date_tree)
  graph.render('images_dates')

# Insert later into the SVG's
#  style="position: absolute;bottom: 1vh;"
# <image xlink:href="qr.gif" width="90px" height="90px" preserveAspectRatio="xMinYMin meet" x="3" y="-170"/>
