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

from . import utilities_uv
from . import utilities_ui
from . import utilities_texel

name_texture = "TT_resize_area"


utilities_ui.icon_register("op_extend_canvas_TL_active.png")
utilities_ui.icon_register("op_extend_canvas_TR_active.png")
utilities_ui.icon_register("op_extend_canvas_BL_active.png")
utilities_ui.icon_register("op_extend_canvas_BR_active.png")



def on_dropdown_size_x(self, context):
	self.size_x = int(self.dropdown_size_x)
	# context.area.tag_redraw()

def on_dropdown_size_y(self, context):
	self.size_y = int(self.dropdown_size_y)
	# context.area.tag_redraw()


class op(bpy.types.Operator):
	bl_idname = "uv.textools_uv_resize"
	bl_label = "Resize Area"
	bl_description = "Resize or extend the UV area"
	bl_options = {'REGISTER', 'UNDO'}

	size_x : bpy.props.IntProperty(
		name = "Width",
		description="padding size in pixels",
		default = 1024,
		min = 1,
		max = 8192
	)
	size_y : bpy.props.IntProperty(
		name = "Height",
		description="padding size in pixels",
		default = 1024,
		min = 1,
		max = 8192
	)
	dropdown_size_x : bpy.props.EnumProperty(
		items = utilities_ui.size_textures, 
		name = "", 
		update = on_dropdown_size_x, 
		default = '1024'
	)
	dropdown_size_y : bpy.props.EnumProperty(
		items = utilities_ui.size_textures, 
		name = "", 
		update = on_dropdown_size_y, 
		default = '1024'
	)

	direction : bpy.props.EnumProperty(name='direction', items=(
		('TL',' ','Top Left', utilities_ui.icon_get("op_extend_canvas_TL_active"),0),
		('BL',' ','Bottom Left', utilities_ui.icon_get("op_extend_canvas_BL_active"),2),
		('TR',' ','Top Right', utilities_ui.icon_get("op_extend_canvas_TR_active"),1),
		('BR',' ','Bottom Right', utilities_ui.icon_get("op_extend_canvas_BR_active"),3)
	))
	
	@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

		return True


	def invoke(self, context, event):
		print("Invoke resize area")
		self.size_x = bpy.context.scene.texToolsSettings.size[0]
		self.size_y = bpy.context.scene.texToolsSettings.size[1]

		for item in utilities_ui.size_textures:
			if int(item[0]) == self.size_x:
				self.dropdown_size_x = item[0]
				break
		for item in utilities_ui.size_textures:
			if int(item[0]) == self.size_y:
				self.dropdown_size_y = item[0]
				break


		return context.window_manager.invoke_props_dialog(self, width = 140)

	def check(self, context):
		return True

	def draw(self, context):
		# https://b3d.interplanety.org/en/creating-pop-up-panels-with-user-ui-in-blender-add-on/
		layout = self.layout


		layout.separator()

		# New Size
		row = layout.row()
		split = row.split(factor=0.6)
		c = split.column(align=True)
		c.prop(self, "size_x", text="X",expand=True)
		c.prop(self, "size_y", text="Y",expand=True)

		c = split.column(align=True)
		c.prop(self, "dropdown_size_x", text="")
		c.prop(self, "dropdown_size_y", text="")

		# Direction
		col = layout.column(align=True)
		col.label(text="Direction")
		row = col.row(align=True)
		row.prop(self,'direction', expand=True)

		# Summary
		size_A = "{} x {}".format(bpy.context.scene.texToolsSettings.size[0], bpy.context.scene.texToolsSettings.size[1])
		if bpy.context.scene.texToolsSettings.size[0] == bpy.context.scene.texToolsSettings.size[1]:
			size_A = "{}²".format(bpy.context.scene.texToolsSettings.size[0])
		size_B = "{} x {}".format(self.size_x, self.size_y)
		if self.size_x == self.size_y:
			size_B = "{}²".format(self.size_x)

		layout.label(text="{} to {}".format(
			size_A, size_B
		))


		layout.separator()

	
	def execute(self, context):

		#Store selection
		utilities_uv.selection_store()

		# Get start and end size
		size_A = Vector([ 
			bpy.context.scene.texToolsSettings.size[0],
			bpy.context.scene.texToolsSettings.size[1]
		])
		size_B = Vector([ 
			self.size_x,
			self.size_y
		])

		resize_uv(
			self,
			context,
			self.direction,
			size_A, 
			size_B
		)
		resize_image(
			context,
			self.direction,
			size_A,
			size_B
		)

		bpy.context.scene.texToolsSettings.size[0] = self.size_x
		bpy.context.scene.texToolsSettings.size[1] = self.size_y

		#Restore selection
		utilities_uv.selection_restore()

		return {'FINISHED'}



def resize_uv(self, context, mode, size_A, size_B):

	# Set pivot
	bpy.context.tool_settings.transform_pivot_point = 'CURSOR'
	if mode == 'TL':
		bpy.ops.uv.cursor_set(location=Vector([0,1]))
	elif mode == 'TR':
		bpy.ops.uv.cursor_set(location=Vector([1,1]))
	elif mode == 'BL':
		bpy.ops.uv.cursor_set(location=Vector([0,0]))
	elif mode == 'BR':
		bpy.ops.uv.cursor_set(location=Vector([1,0]))

	# Select all UV faces
	bpy.ops.uv.select_all(action='SELECT')

	# Resize
	scale_x = size_A.x / size_B.x
	scale_y = size_A.y / size_B.y
	bpy.ops.transform.resize(value=(scale_x, scale_y, 1.0), use_proportional_edit=False)



def resize_image(context, mode, size_A, size_B):
	print("resize image {}".format( context.area.spaces ))

	# Notes: 	https://blender.stackexchange.com/questions/31514/active-image-of-uv-image-editor
	# 			https://docs.blender.org/api/blender_python_api_2_70_4/bpy.types.SpaceImageEditor.html


	if context.area.spaces.active != None:
		if context.area.spaces.active.image != None:
			image = context.area.spaces.active.image
			image_obj = utilities_texel.get_object_texture_image(bpy.context.active_object)
			if name_texture in image.name or image == image_obj:
				# Resize Image UV editor background image
				utilities_texel.image_resize(image, int(size_B.x), int(size_B.y))

		else:
			# No Image assigned

			# Get background color from theme + 1.25x brighter
			theme = bpy.context.preferences.themes[0]
			color = theme.image_editor.space.back.copy()
			color.r*= 1.15
			color.g*= 1.15
			color.b*= 1.15

			image = None
			if name_texture in bpy.data.images:
				# TexTools Image already exists
				image = bpy.data.images[name_texture]
				image.scale( int(size_B.x), int(size_B.y) )
				image.generated_width = int(size_B.x)
				image.generated_height = int(size_B.y)
			else:
				# Create new image
				image = bpy.data.images.new(name_texture, width=int(size_B.x), height=int(size_B.y))
				image.generated_color = (color.r, color.g, color.b, 1.0)
				image.generated_type = 'BLANK'
				image.generated_width = int(size_B.x)
				image.generated_height = int(size_B.y)

			# Assign in UV view
			context.area.spaces.active.image = image

		# Clean up images and materials
		utilities_texel.checker_images_cleanup()



bpy.utils.register_class(op)