#!/usr/bin/env python
# vim: set fileencoding=utf-8
# pylint: disable=C0103

"""
Module to insert potree in jupyter notebooks and colab

Copyright (C) 2019, Gabriele Facciolo <gfacciol@gmail.com>
"""

from os import path
BIN = path.dirname(__file__)+'/bin'


# this function displays a 3D point cloud using the potree viewer
def generate_cloud_for_display(xyz):
	"""
	Display a point cloud inside a jupyter IFrame

	Arguments:
		xyz: a Nx3 matrix containing the 3D positions of N points
	"""
	import os
	import shutil
	import numpy as np

	# note: if you want to add color intensities to your points, use a Nx4 array and then change
	# the "-parse" option below to xyzi.  Similarly for RGB color, save an Nx6 array

	# clear output dir
	#try:
	#	shutil.rmtree('point_clouds')
	#except FileNotFoundError:
	#	pass
	import uuid
	unique_dirname = str(uuid.uuid4())[:6]

	# dump data and convert
	np.savetxt(".tmp.txt", xyz)
	print("{BIN}/PotreeConverter .tmp.txt -f xyz -o point_clouds -p {idd} --material ELEVATION --edl-enabled --overwrite".format(BIN=BIN, idd=unique_dirname))
	os.system("{BIN}/PotreeConverter .tmp.txt -f xyz -o point_clouds -p {idd} --material ELEVATION --edl-enabled --overwrite".format(BIN=BIN, idd=unique_dirname))


	return ('{idd}'.format(idd=unique_dirname))
 




def display_cloud(path, width=980, height=800):
	"""
	Display a point cloud in the path generated by generate_cloud_for_display
	Arguments:
		xyz: a Nx3 matrix containing the 3D positions of N points
		width=980, height=800: size of the canvas
	"""
	from IPython.display import IFrame
	return IFrame('point_clouds/'+path+'.html', width=width, height=height)




port = 0

def display_cloud_colab(xyz):
	"""
	Display a point cloud in the path generated by generate_cloud_for_display

	Arguments:
		xyz: a Nx3 matrix containing the 3D positions of N points
	"""

	global port

	if port == 0: 
		import portpicker
		import threading
		import socket
		import IPython

		from six.moves import socketserver
		from six.moves import SimpleHTTPServer

		import time

		class V6Server(socketserver.TCPServer):
			address_family = socket.AF_INET6

		class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
			def do_GET(self):
				#super().do_GET()
				self.send_response(200)
				# If the response should not be cached in the notebook for
				# offline access:
				self.send_header('x-colab-notebook-cache-control', 'no-cache')
				self.end_headers()
				
				#self.wfile.write(b'''hola!''')
				self.wfile.write(b'''
				    document.querySelector('#output-area').appendChild(document.createTextNode('Script result!'));
                    ''')
		#global port
		port = portpicker.pick_unused_port()

		### SERVING ALL THE FILES
		Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

		def server_entry():
			httpd = V6Server(('::', port), Handler)
			# Handle a single request then exit the thread.
			httpd.serve_forever()

		thread = threading.Thread(target=server_entry)
		thread.start()
  
		print ("server on port {}: thread {} ".format( port, thread ) )


	text = open('point_clouds/{}.html'.format(xyz) ).read()

	pointcloudpath='https://localhost:{port}/point_clouds/pointclouds/{xyz}'.format(port=port, xyz=xyz)

	print (pointcloudpath)

	newtext = text.replace('src="', 'src="https://localhost:{port}/point_clouds/'.format(port=port))
	newtext = newtext.replace('href="', 'href="https://localhost:{port}/point_clouds/'.format(port=port))
	#newtext = newtext.replace('"pointclouds/', '"https://localhost:{port}/pointclouds/'.format(port=port))
	newtext = newtext.replace('pointclouds/{}'.format(xyz), pointcloudpath)

	newtext = newtext.replace('width: 100%; height: 100%;', 'width: 100%; height: 500px;')
	newtext = newtext.replace('libs/potree/potree.js', 'libs/potree/potree.colab.js' )

	import IPython

	return IPython.display.HTML(newtext)
 
