#!/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 ('pointclouds/{idd}'.format(idd=unique_dirname))
 




def display_cloud(path):
	"""
	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
	"""
	from IPython.display import IFrame
	return IFrame(path+'.html', width=980, height=800)





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 os
		#os.chdir('/content/point_clouds/')


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

		class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
			def do_GET(self):
				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!'));
				''')

		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 (port)
		print (thread)
		import time
		time.sleep(1)



	text="""
		<!DOCTYPE html>
		<html lang="en">
		<head>
			<meta charset="utf-8">
			<meta name="description" content="">
			<meta name="author" content="">
			<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
			<title>Potree Viewer</title>

			<link rel="stylesheet" type="text/css" href="libs/potree/potree.css">
			<link rel="stylesheet" type="text/css" href="libs/jquery-ui/jquery-ui.min.css">
			<link rel="stylesheet" type="text/css" href="libs/perfect-scrollbar/css/perfect-scrollbar.css">
			<link rel="stylesheet" href="libs/openlayers3/ol.css" type="text/css">
			<link rel="stylesheet" href="libs/spectrum/spectrum.css" type="text/css">
		</head>

		<body>
		
			<script src="libs/jquery/jquery-3.1.1.js"></script>
			<script src="libs/spectrum/spectrum.js"></script>
			
			<script src="libs/perfect-scrollbar/js/perfect-scrollbar.jquery.js"></script>
			<script src="libs/jquery-ui/jquery-ui.min.js"></script>
			<script src="libs/three.js/build/three.js"></script>
			<script src="libs/other/stats.min.js"></script>
			<script src="libs/other/BinaryHeap.js"></script>
			<script src="libs/tween/tween.min.js"></script>
			<script src="libs/d3/d3.js"></script>
			<script src="libs/proj4/proj4.js"></script>
			<script src="libs/openlayers3/ol.js"></script>
			<script src="libs/i18next/i18next.js"></script>
			
			<script src="libs/potree/potree.colab.js"></script>
			
			<script src="libs/plasio/js/laslaz.js"></script>
			<script src="libs/plasio/vendor/bluebird.js"></script>

			<div class="potree_container" style="position: absolute; width: 100%; height: 500px; left: 0px; top: 0px; ">
				<div id="potree_render_area"></div>
				<div id="potree_sidebar_container"> </div>
			</div>
			
			<script>
			
				window.viewer = new Potree.Viewer(document.getElementById("potree_render_area"));
				
				viewer.setEDLEnabled(true);
				viewer.setFOV(60);
				viewer.setPointBudget(1*1000*1000);
				document.title = "";
				viewer.setEDLEnabled(true);
				viewer.setBackground("gradient"); // ["skybox", "gradient", "black", "white"];
				viewer.setDescription(``);
				viewer.loadSettingsFromURL();
				
				viewer.loadGUI(() => {
					viewer.setLanguage('en');
					$("#menu_tools").next().show();
					//viewer.toggleSidebar();
				});
				
				Potree.loadPointCloud("pointcloudpath/cloud.js", "test", e => {
					let pointcloud = e.pointcloud;
					let material = pointcloud.material;
					viewer.scene.addPointCloud(pointcloud);
					material.pointColorType = Potree.PointColorType.ELEVATION; // any Potree.PointColorType.XXXX 
					material.size = 1;
					material.pointSizeType = Potree.PointSizeType.ADAPTIVE;
					material.shape = Potree.PointShape.SQUARE;
					viewer.fitToScreen();
				});
				
			</script>
			
			
		</body>
		</html>
	"""

	pointcloudpath='https://localhost:{port}/point_clouds/{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('pointcloudpath', pointcloudpath)



	import IPython

	return IPython.display.HTML(newtext)
 


