#-------------------------------------------------------------------------------
# Name:		    DrawPerpendicular.py
# Purpose:      Draw perpendicular to the mid points of each coastline segments.
#
#
# Author:		Dr. Arghya Goswami
# Contact:		arghya.goswami@gmail.com
#
# Created:		14/03/2014
#
# Copyright:	(c) Dr. Arghya Goswami 2014
#
# Licence:		This program is free software; you can redistribute it and/or
#			    modify it under the terms of the GNU General Public License,
#			    version 2, as published by the Free Software Foundation.
#
#			    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, write to:
#
#			    Free Software Foundation, Inc.,
#			    51 Franklin St, Fifth Floor,
#			    Boston, MA, 02110-1301  USA
#-------------------------------------------------------------------------------
#!/usr/bin/env python
#-------------------------------------------------------------------------------
import arcpy, sets, numpy, sys, os, shutil, glob, time, fileinput, string, Tkinter, tkFileDialog
from Tkinter import *
##from arcpy.sa import *
if arcpy.CheckExtension("3D") == "Available":
	arcpy.CheckOutExtension("3D")
if arcpy.CheckExtension("GeoStats") == "Available":
	arcpy.CheckOutExtension("GeoStats")
if arcpy.CheckExtension("Spatial") == "Available":
	arcpy.CheckOutExtension("Spatial")
"""-----------------------------------------------------------------------------
# Start Time
-----------------------------------------------------------------------------"""
StartTime = time.asctime(time.localtime(time.time()))
print "Start Time: ", StartTime,"\n"
"""-----------------------------------------------------------------------------
# Check Script name
-----------------------------------------------------------------------------"""
scriptname = os.path.basename(__file__)
if "module" in scriptname:
	print "Please SAVE the script with a Meaningful NAME and RE-RUN!\n"
"""-----------------------------------------------------------------------------
# Definitions used in this Script
-----------------------------------------------------------------------------"""
# Browse a file function
def BrowseFile(msg1,indir,ext):
	#Creating Main Window
	root = Tk()
	if ext == "csv":
		desc1 = "Comma Seperated Value Files"
		desc2 = "*." + ext
	elif ext == "txt":
		desc1 = "Text Files"
		desc2 = "*." + ext
	elif ext == "shp":
		desc1 = "Shape Files"
		desc2 = "*." + ext
	elif ext == "cdf":
		desc1 = "Common Data Format Files"
		desc2 = "*." + ext
	# Creating Secondary Window for File Browsing
	filename = tkFileDialog.askopenfilename(filetypes = [(desc1,desc2),('All files','*')], title = msg1, initialdir = indir)
	# Close the Main Window
	root.withdraw()
	# Return Filename
	return filename

# Browse a directory function
def BrowseDir(msg2,indir):
	#Creating Main Window
	root = Tk()
	# Creating Secondary Window for Folder Browsing
	dirname = tkFileDialog.askdirectory(title = msg2, initialdir=indir)
	# Close the Main Window
	root.withdraw()
	# Return Dirname
	return dirname

# Check the existance of a directory function
def DirCheck(filename):
	# Check if the string is a file name or directory name
	if filename[len(filename)-4] == ".":
		dname = os.path.dirname(filename)
	else:
		dname = filename
	# Check if Dir exists, else create
	if os.path.exists(dname):
		pass
	else:
		os.mkdir(dname)
	# Check if the path name if Dir ends with a '/' else add it
	if dname[(len(dname)-1):]=="\\" or dname[(len(dname)-1):] == "/":
		dpath = dname
	else:
		dpath = dname + "/"
	return dpath

def AllfFields(infile):
	global FieldNnames
	fields = arcpy.ListFields(infile)
	FieldNnames = []
	for field in fields:
		FieldNnames.append(field.name)
	return FieldNnames

# Create the list of files in a folder
def getFileList(root,ext):
	# for folder path either use "Browse"/"browse" or provide the path to a folder
	# for all filetypes send extention as an empty string (""), else use like ".csv"
	global filelist
	if root == "Browse" or root == "browse":
		root = BrowseDir("Please select the Directory", "C:/")
		# select the type of file, for instance *.jpg or all files *.*
		for folder in glob.glob(root):
			print "Files in", folder, "is being populated to a list"
			if ext == "":
				ext = "/*.*"
			else:
				ext = "/*" + ext
		for file in glob.glob(folder + ext):
			# retrieves the stats for the current file as a tuple
			# (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)
			# the tuple element mtime at index 8 is the last-modified-date
			filelist.append(file)
	print "\nFile List Prepared, starting to list them......\n"
"""-----------------------------------------------------------------------------
# Main Script
-----------------------------------------------------------------------------"""
# Search Cursor
inFC = BrowseFile("Select Shapefile","C:/","shp")
transDist = raw_input("Please enter the length of perpendicularlines in meters")         # Distance in meters and must use projected shapefile
outFC = arcpy.CreateFeatureclass_management(os.path.dirname(inFC),(os.path.basename(inFC)).replace(".shp","_midptprependicularx1y1.shp"),"POLYLINE",'','','',arcpy.Describe(inFC).spatialReference) #n inFC.replace(".shp", "_Perp.shp")
cursor = arcpy.da.InsertCursor(outFC, ["SHAPE@"])
for row in arcpy.da.SearchCursor(inFC, ["OID@", "SHAPE@"]):
	# Print the current line ID
	print("Processing Feature {0}:".format(row[0]))

	#Set start point
	startpt = row[1].firstPoint
	startx = startpt.X
	starty = startpt.Y
	#Set mid point
	midpt = row[1].positionAlongLine(0.5,TRUE).firstPoint
	midx = midpt.X
	midy = midpt.Y
	#Set end point
	endpt = row[1].lastPoint
	endx = endpt.X
	endy = endpt.Y

	#print "/tStart X: ", str(startx), ", Start Y: ", str(starty), ", End X; ", str(endx), ", End Y: ", str(endy), "\n"
	pts = [(midx,midy)] #[(startx,starty),(midx,midy),(endx,endy)]
	for items in pts:
		ix = items[0]
		iy = items[1]
		if starty==endy or startx==endx:
			if starty == endy:
				y1 = iy + transDist
				x1 = ix
			if startx == endx:
				y1 = iy
				x1 = ix + transDist
		else:
			# Get slope of line
			m = ((starty - endy)/(startx - endx))
			# Get negative reciprocal
			negativereciprocal = -1*((startx - endx)/(starty - endy))
			# For all values of slope, calculate perpendicular line
			# with length = transDist
			if m > 0:
				if m >= 1:
					y1 = negativereciprocal*(transDist)+ iy
					x1 = ix + transDist
				if m < 1:
					y1 = iy + transDist
					x1 = (transDist/negativereciprocal) + ix
			if m < 0:
				if m >= -1:
					y1 = iy + transDist
					x1 = (transDist/negativereciprocal) + ix
				if m < -1:
					y1 = negativereciprocal*(transDist)+ iy
					x1 = ix + transDist
		array = arcpy.Array([arcpy.Point(ix, iy), arcpy.Point(x1, y1)])
		polyline = arcpy.Polyline(array)
		cursor.insertRow([polyline])
		del x1, y1, array, polyline
del cursor
"""-----------------------------------------------------------------------------
# End Time
-----------------------------------------------------------------------------"""
EndTime = time.asctime(time.localtime(time.time()))
print "\nEnd Time: ", EndTime,"\n"