import bpy
import bmesh
import operator
from mathutils import Vector
from collections import defaultdict
from math import pi

from . import utilities_uv
import imp
imp.reload(utilities_uv)

class op(bpy.types.Operator):
	bl_idname = "uv.textools_select_islands_flipped"
	bl_label = "Select Flipped"
	bl_description = "Select all flipped UV islands"
	bl_options = {'REGISTER', 'UNDO'}

	@classmethod
	def poll(cls, context):
		if not bpy.context.active_object:
			return False

		if bpy.context.active_object.type != 'MESH':
			return False

		#Only in Edit mode
		if bpy.context.active_object.mode != 'EDIT':
			return False

		#Only in UV editor mode
		if bpy.context.area.type != 'IMAGE_EDITOR':
			return False

		##Requires UV map
		if not bpy.context.object.data.uv_layers:
			return False

		#Not in Synced mode
		if bpy.context.scene.tool_settings.use_uv_select_sync:
			return False
			
		return True


	def execute(self, context):
		
		select_flipped(context)
		return {'FINISHED'}



def select_flipped(context):
	bm = bmesh.from_edit_mesh(bpy.context.active_object.data)
	uv_layers = bm.loops.layers.uv.verify()

	bpy.context.scene.tool_settings.uv_select_mode = 'FACE'
	bpy.ops.uv.select_all(action='SELECT')

	islands = utilities_uv.getSelectionIslands()
	

	bpy.context.scene.tool_settings.uv_select_mode = 'FACE'
	bpy.context.scene.tool_settings.use_uv_select_sync = False
	bpy.ops.uv.select_all(action='DESELECT')


	for island in islands:

		is_flipped = False
		for face in island:
			if is_flipped:
				break

			# Using 'Sum of Edges' to detect counter clockwise https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
			sum = 0
			count = len(face.loops)
			for i in range(count):
				uv_A = face.loops[i][uv_layers].uv
				uv_B = face.loops[(i+1)%count][uv_layers].uv
				sum += (uv_B.x - uv_A.x) * (uv_B.y + uv_A.y)

			if sum > 0:
				# Flipped
				is_flipped = True
				break

		# Select Island if flipped
		if is_flipped:
			for face in island:
				for loop in face.loops:
					loop[uv_layers].select = True




class Island_bounds:
	faces = []
	center = Vector([0,0])
	min = Vector([0,0])
	max = Vector([0,0])

	def __init__(self, faces):
		bm = bmesh.from_edit_mesh(bpy.context.active_object.data);
		uv_layers = bm.loops.layers.uv.verify();
		
		# Collect topology stats
		self.faces = faces

		#Select Island
		bpy.ops.uv.select_all(action='DESELECT')
		utilities_uv.set_selected_faces(faces)

		bounds = utilities_uv.getSelectionBBox()
		self.center = bounds['center']
		self.min = bounds['min']
		self.max = bounds['max']


		
	def isEqual(A, B):

		# Bounding Box AABB intersection?
		min_x = max(A.min.x, B.min.x)
		min_y = max(A.min.y, B.min.y)
		max_x = min(A.max.x, B.max.x)
		max_y = min(A.max.y, B.max.y)
		if not (max_x < min_x or max_y < min_y):
			return True
		

		return False

bpy.utils.register_class(op)