### /filter/resize.py

import wx
from gui.imageimport import *

from obj.objImage  import objImage
from obj.objFilter import objFilter
from obj.objGrid   import grid
from gui.colorPanel import *

from getInput import *
from setOutput import *

### properties
### ["resize",
###  r = (rw, rh), 		# resize width and height
###  ru = (rwu, rhu),	# resize unit 
###  rs = (rws, rhs), 	# resize string
###	 ColorBack			# strip's backcolor
### ] 

d = 96

unitList = ['%', 'px']

def getStrip(string):
	data = []
	tmp = ''
	for s in string:
		if s in '0123456789':
			tmp = tmp + s
		else:
			if tmp <> '':
				data.append(int(tmp))
				tmp = ''
	if tmp <> '':
		data.append(int(tmp))
	return data

def divideUnit(w,unit):
	if unit <> []:
		# make unit
		wu, wui = 0, 0		# width's unit, width's image unit
		for i in range(len(unit)):       wu  += unit[i]
		for i in range(0, len(unit), 2): wui += unit[i]
		if wui == 0: return None
		loop = int(w / wui)
		# left image that cannot divide by unit
		left = w - loop * wui
		leftResized = 0
		i = 0
		while left >= unit[i]:	# [(1), 1, (3), 2]
			left -= unit[i]
			if i + 1 < len(unit):
				leftResized += unit[i] + unit[i + 1]
			else:
				leftResized += unit[i]
			i += 2
		leftResized += left
		w = (loop * wu) + leftResized
		return w
	else:
		return None

def resize(obj):
	p = get_properties_resize(obj)
	if len(obj.datainput) > 0:
		### resize
		if p.ru[0] == 1:
			w = p.r[0]
		else:
			w = int(obj.datainput[0].size[0] * (p.r[0] / 100.0))
		if p.ru[1] == 1:
			h = p.r[1]
		else:
			h = int(obj.datainput[0].size[1] * (p.r[1] / 100.0))
		oldImage = obj.datainput[0].copy().resize((w,h))
		
		### functional method
		# First, get strip's data
		datax = getStrip(p.rs[0])
		datay = getStrip(p.rs[1])
		
		# Second-w, Resize newImage
		rw = divideUnit(w, datax)
		
		if rw <> None:
			# copy oldImage to middleImage
			middleImage = Image.new('RGB', (rw, h), p.ColorBack)
			
			l, x1, i = 0, 0, 0
			while l < w:
				if i % 2 == 0:
					if datax[i] <> 0 :
						box = oldImage.crop((l, 0, l + datax[i], h))
						middleImage.paste(box, (x1, 0, x1 + datax[i], h))		
						l += datax[i]
				x1 += datax[i]
				i  += 1
				if len(datax) == i: i = 0
			if i == 0:
				i = len(datax) - 1
			else:
				i -= 1
		else:
			middleImage = oldImage
		
		# Second-h, Resize newImage
		if rw == None: rw = w
		rh = divideUnit(h, datay)
		if rh <> None:
			# copy oldImage to middleImage
			newImage = Image.new('RGB', (rw, rh), p.ColorBack)
			
			l, y1, i = 0, 0, 0
			while l < h:
				if i % 2 == 0:
					if datay[i] <> 0 :
						box = middleImage.crop((0, l, rw, l + datay[i]))
						newImage.paste(box, (0, y1, rw, y1 + datay[i]))		
						l += datay[i]
				y1 += datay[i]
				i  += 1
				if len(datay) == i: i = 0
			if i == 0:
				i = len(datay) - 1
			else:
				i -= 1
		else:
			newImage = middleImage
		
		obj.dataoutput = newImage
	else:
		obj.dataoutput = None

class get_properties_resize:
	def __init__(self,obj):
		if len(obj.properties) == 5:
			self.r           = obj.properties[1]
			self.ru          = obj.properties[2]
			self.rs          = obj.properties[3]
			self.ColorBack   = obj.properties[4]
		else:
			self.r           = (100, 100)
			self.ru          = (0,0)		# 0 -> %, 1 -> px
			self.rs          = ['', '']
			self.ColorBack   = (255,255,255)

class resizeUI:
	def __init__(self,panel,obj):
		self.obj = obj
		self.p = get_properties_resize(self.obj)
		self.panel = panel
		getInput(self.obj,self.panel.frame)
		
		if len(self.obj.datainput) < 1:
			self.panel.frame.Close(True)
		elif not isinstance(obj.datainput[0],Image.Image):
			self.panel.frame.Close(True)
		else:
			self.gui()
	
	def gui(self):
		# make pil_input_thumbnail picture and wxinput
		self.datainputh = self.obj.datainput[0].copy()
		self.datainputh.thumbnail((d,d),Image.ANTIALIAS)
		
		self.wxinput = wx.EmptyImage(self.datainputh.size[0], self.datainputh.size[1])
		self.wxinput.SetData(self.datainputh.convert('RGB').tostring())
		
		# make dataoutput's copy
		if self.obj.dataoutput == None:
			self.obj.dataoutput = self.obj.datainput[0].copy()
		
		# make pil_output_thumbnail picture and wxoutput
		self.dataoutputh = self.obj.dataoutput.copy()
		self.dataoutputh.thumbnail((d, d), Image.ANTIALIAS)
		
		self.wxoutput = wx.EmptyImage(self.dataoutputh.size[0], self.dataoutputh.size[1])
		self.wxoutput.SetData(self.dataoutputh.convert('RGB').tostring())
		
		#-- make gui
		self.panel.frame.SetSize((386,310))
		
		#-- LeftSize
		LeftSize = wx.BoxSizer(wx.VERTICAL)
		
		self.wxginput = wx.StaticBitmap(self.panel, -1, self.wxinput.ConvertToBitmap(),	\
					   (self.wxinput.GetWidth(), self.wxinput.GetHeight()))
		self.wxgoutput = wx.StaticBitmap(self.panel, -1, self.wxoutput.ConvertToBitmap(), \
					   (self.wxoutput.GetWidth(), self.wxoutput.GetHeight()))
		LeftSize.Add(self.wxginput,0,wx.FIXED_MINSIZE | wx.BOTTOM, 5)
		LeftSize.Add(self.wxgoutput,0,wx.FIXED_MINSIZE | wx.ALIGN_RIGHT, 5)
		
		#-- Right
		RightSize = wx.BoxSizer(wx.VERTICAL)
		
		# Right-Top
		box1 = wx.StaticBox(self.panel,-1, "Resize")
		RightTopSize = wx.StaticBoxSizer(box1, wx.VERTICAL)
		box1Size1 = wx.BoxSizer()
		box1Size2 = wx.BoxSizer()
		
		self.LabelW = wx.StaticText(self.panel, -1," w : ")
		self.TextW = wx.TextCtrl(self.panel, -1, "10", size = wx.DefaultSize)
		self.panel.Bind(wx.EVT_TEXT, self.OnTextW, self.TextW)
		self.ChoiceUnitW = wx.Choice(self.panel, -1, choices = unitList)
		self.panel.Bind(wx.EVT_CHOICE, self.OnChoiceUnitW, self.ChoiceUnitW)
		box1Size1.Add(self.LabelW,0,wx.FIXED_MINSIZE | wx.LEFT |  wx.TOP, 5)
		box1Size1.Add(self.TextW,0,wx.FIXED_MINSIZE | wx.TOP, 5)
		box1Size1.Add(self.ChoiceUnitW,0,wx.FIXED_MINSIZE | wx.LEFT | wx.RIGHT | wx.TOP, 5)
		
		self.LabelH = wx.StaticText(self.panel, -1," h : ")
		self.TextH = wx.TextCtrl(self.panel, -1, "10", size = wx.DefaultSize)
		self.panel.Bind(wx.EVT_TEXT, self.OnTextH, self.TextH)
		self.ChoiceUnitH = wx.Choice(self.panel, -1, choices = unitList)
		self.panel.Bind(wx.EVT_CHOICE, self.OnChoiceUnitH, self.ChoiceUnitH)
		box1Size2.Add(self.LabelH,0,wx.FIXED_MINSIZE | wx.LEFT | wx.TOP, 5)
		box1Size2.Add(self.TextH,0,wx.FIXED_MINSIZE | wx.TOP, 5)
		box1Size2.Add(self.ChoiceUnitH,0,wx.FIXED_MINSIZE | wx.LEFT | wx.RIGHT | wx.TOP, 5)
		
		RightTopSize.Add(box1Size1, 0, wx.EXPAND | wx.LEFT | wx.RIGHT , 5)
		RightTopSize.Add(box1Size2, 0, wx.EXPAND | wx.LEFT |wx.BOTTOM , 5)
		
		# Right-Middle		
		box2 = wx.StaticBox(self.panel,-1, "Function")
		RightMiddleSize = wx.StaticBoxSizer(box2, wx.VERTICAL)
		
		box2Size1 = wx.BoxSizer()
		box2Size2 = wx.BoxSizer()
		box2Size3 = wx.BoxSizer()
		
		self.ButtonColorBack  = ColorPanel(self.panel)
		self.panel.Bind(EVT_CHANGE_COLOR, self.OnChangeColorBack, \
			id = self.ButtonColorBack.GetId())
		self.LabelColorBack = wx.StaticText(self.panel, -1,"BackColor : ")
		box2Size1.Add(self.LabelColorBack, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP , 5)
		box2Size1.Add(wx.DefaultSize, 1, wx.EXPAND)
		box2Size1.Add(self.ButtonColorBack, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP , 5)
		
		self.LabelX = wx.StaticText(self.panel, -1," x : ")
		self.TextX = wx.TextCtrl(self.panel, -1, "", size = wx.DefaultSize)
		self.panel.Bind(wx.EVT_TEXT, self.OnTextX, self.TextX)
		box2Size2.Add(self.LabelX,0,wx.FIXED_MINSIZE | wx.LEFT | wx.TOP, 5)
		box2Size2.Add(self.TextX,1,wx.EXPAND | wx.TOP, 5)
		
		self.LabelY = wx.StaticText(self.panel, -1," y : ")
		self.TextY = wx.TextCtrl(self.panel, -1, "", size = wx.DefaultSize)
		self.panel.Bind(wx.EVT_TEXT, self.OnTextY, self.TextY)
		box2Size3.Add(self.LabelY,0,wx.FIXED_MINSIZE | wx.LEFT | wx.TOP, 5)
		box2Size3.Add(self.TextY,1,wx.EXPAND | wx.TOP, 5)
		
		RightMiddleSize.Add(box2Size1, 0, wx.EXPAND | wx.TOP | wx.LEFT , 5)
		RightMiddleSize.Add(box2Size2, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5)
		RightMiddleSize.Add(box2Size3, 0, wx.EXPAND | wx.ALL, 5)
		
		RightBottomSize = wx.BoxSizer()
		
		ButtonResize = wx.Button(self.panel, -1, "Resize")
		self.panel.Bind(wx.EVT_BUTTON, self.ImageRefresh, ButtonResize)	
		ButtonClose = wx.Button(self.panel, -1, "Close")
		self.panel.Bind(wx.EVT_BUTTON, self.OnCloseMe, ButtonClose)
		
		RightBottomSize.Add(ButtonResize,0,wx.FIXED_MINSIZE , 5)
		RightBottomSize.Add(wx.DefaultSize, 1, wx.EXPAND)
		RightBottomSize.Add(ButtonClose,0,wx.FIXED_MINSIZE | wx.ALIGN_RIGHT, 5)
		
		RightSize.Add(RightTopSize, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP , 5)
		RightSize.Add(RightMiddleSize, 0, wx.EXPAND | wx.ALL, 5)
		RightSize.Add(RightBottomSize, 1, wx.EXPAND | wx.ALL, 5)
		
		MainSize = wx.BoxSizer()
		MainSize.Add(LeftSize, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP , 10)
		MainSize.Add(RightSize, 1, wx.EXPAND | wx.ALL, 10)
		
		self.panel.SetSizer(MainSize)
		
		self.SetValueUI()
	def OnTextW(self, e):
		if self.TextW.GetValue()!="":
			i = int(self.TextW.GetValue())
			if (0 > i):
				self.TextW.SetValue('100')
				i = 100
			self.p.r = (i, self.p.r[1])
	def OnTextH(self, e):
		if self.TextH.GetValue()!="":
			i = int(self.TextH.GetValue())
			if (0 > i):
				self.TextH.SetValue('100')
				i = 100
			self.p.r = (self.p.r[0], i)
	def OnTextX(self, e):
		self.p.rs[0] = self.TextX.GetValue()
	def OnTextY(self, e):
		self.p.rs[1] = self.TextY.GetValue()
	def OnChoiceUnitW(self, e):
		self.p.ru = (self.ChoiceUnitW.GetSelection(), self.p.ru[1])
	def OnChoiceUnitH(self, e):
		self.p.ru = (self.p.ru[0], self.ChoiceUnitH.GetSelection())
	def OnChangeColorBack(self, e):
		self.p.ColorBack = e.GetColor()
	def ImageRefresh(self ,e = None):
		# make dataoutput with PIL function "resize"
		self.SetValueObj()
		self.dataoutput = resize(self.obj)
		
		# make pil_output_thumbnail picture and wxoutput
		self.dataoutputh = self.obj.dataoutput.copy()
		self.dataoutputh.thumbnail((d,d),Image.ANTIALIAS)
		
		self.wxoutput = wx.EmptyImage(self.dataoutputh.size[0], self.dataoutputh.size[1])
		self.wxoutput.SetData(self.dataoutputh.convert('RGB').tostring())
		
		# refresh!
		self.wxgoutput.SetBitmap(self.wxoutput.ConvertToBitmap())
	def SetValueObj(self):
		self.obj.properties = \
			['resize', \
			 self.p.r, \
			 self.p.ru, \
			 self.p.rs, \
			 self.p.ColorBack]		
	def SetValueUI(self):
		# r, ru, rs
		self.TextW.SetValue(str(self.p.r[0]))
		self.TextH.SetValue(str(self.p.r[1]))
		self.TextX.SetValue(str(self.p.rs[0]))
		self.TextY.SetValue(str(self.p.rs[1]))
		self.ChoiceUnitW.Select(self.p.ru[0])
		self.ChoiceUnitH.Select(self.p.ru[1])
		self.ButtonColorBack.SetColor(self.p.ColorBack)
		
	def OnCloseMe(self,e):
		# make shape's bitmap
		self.SetValueObj()
		self.obj.PreviewBitmap()
		setOutput(self.obj,self.panel.frame)
		# dismiss
		self.panel.frame.Close(True)

