### /gui/imageMake.py

import wx
from gui.imageimport import *

import sets
from obj.objImage import objImage 
from obj.objFilter import objFilter
from gui.colorPanel import *
from filter.filter import filterPanel
from filter.setOutput import setOutput

from math import *

class ImageMakeView(wx.Frame):
	def __init__(self,frame,obj=None):
		self.frame = frame
		wx.Frame.__init__(self,frame,-1,"imageMake", 
							  style=wx.DEFAULT_FRAME_STYLE | wx.TINY_CAPTION_HORIZ)
	
		self.pil = None
		self.obj = obj
		
		# make gui
		self.gui()
		self.Show()
	def gui(self):
		self.SetSize((420,318))
		
		### Left
		LeftSize = wx.BoxSizer(wx.VERTICAL)
		
		#  Left-Canvas
		self.Canvas = ImageCanvas(self)
		
		#  Left-Panel 
		LeftPanelSize = wx.BoxSizer(wx.HORIZONTAL)
		
		ButtonColor = ColorPanel(self)
		self.Bind(EVT_CHANGE_COLOR, self.OnChangeColor, \
			id = ButtonColor.GetId())
		
		ButtonPlot = wx.Button(self, -1, "Plot")
		self.Bind(wx.EVT_BUTTON, self.OnPlot, ButtonPlot)
		
		self.TextPlot = wx.TextCtrl(self, -1, "x==y", size=wx.DefaultSize)
		
		LeftPanelSize.Add(ButtonColor,0,wx.EXPAND)
		LeftPanelSize.Add(self.TextPlot,1,wx.EXPAND | wx.LEFT,10)
		LeftPanelSize.Add(ButtonPlot,0,wx.FIXED_MINSIZE | wx.LEFT,10)
		
		### Left-End
		LeftSize.Add(self.Canvas,1,wx.EXPAND | wx.LEFT | wx.TOP, 10)
		LeftSize.Add(LeftPanelSize,0,wx.EXPAND | wx.LEFT| wx.BOTTOM | wx.TOP, 10)
		
		### Right
		RightSize = wx.BoxSizer(wx.VERTICAL)
		
		box = wx.StaticBox(self,-1, "Image Detail")
		
		self.LabelXY = wx.StaticText(self, -1,"")
		self.Canvas.LabelXY = self.LabelXY
		
		self.LabelWH = wx.StaticText(self, -1,"")
		self.Canvas.LabelWH = self.LabelWH
		
		self.Check1 = wx.CheckBox(self,-1,"Fixed pixel")
		self.Bind(wx.EVT_CHECKBOX, self.OnCheckFixed, self.Check1)
		checkFlag = False
		
		self.LabelW = wx.StaticText(self, -1,"w:")
		if self.obj <> None:
			if self.obj.image.size[0] <= 64:
				self.TextW = wx.TextCtrl(self, -1, str(self.obj.image.size[0]), size=wx.DefaultSize)
				checkFlag = True
			else:
				self.TextW = wx.TextCtrl(self, -1, "1", size=wx.DefaultSize)
		else:
			self.TextW = wx.TextCtrl(self, -1, "1", size=wx.DefaultSize)
		self.Bind(wx.EVT_TEXT, self.OnTextW, self.TextW)
		
		self.LabelH = wx.StaticText(self, -1,"h:")
		if checkFlag == True:
			if self.obj <> None:
				if self.obj.image.size[1] <= 64:
					self.TextH = wx.TextCtrl(self, -1, str(self.obj.image.size[1]), size=wx.DefaultSize)
					checkFlag = True
				else:
					self.TextH = wx.TextCtrl(self, -1, "1", size=wx.DefaultSize)
					checkFlag = False
			else:
				self.TextH = wx.TextCtrl(self, -1, "1", size=wx.DefaultSize)
				checkFlag = False
		else:
			self.TextH = wx.TextCtrl(self, -1, "1", size=wx.DefaultSize)
			
				
		self.Bind(wx.EVT_TEXT, self.OnTextH, self.TextH)
		
		TextSize = wx.FlexGridSizer(cols=2, hgap=10, vgap=10)
		TextSize.AddMany([self.LabelW,self.TextW, \
						  self.LabelH,self.TextH])
		
		BSize = wx.StaticBoxSizer(box, wx.VERTICAL)
		BSize.Add(self.LabelXY,0,wx.RIGHT | wx.LEFT | wx.TOP,10)
		BSize.Add(self.LabelWH,0,wx.RIGHT | wx.LEFT | wx.TOP,10)
		BSize.Add(self.Check1,0,wx.RIGHT | wx.LEFT | wx.TOP,10 )
		BSize.Add(TextSize,0, wx.RIGHT | wx.LEFT | wx.TOP | wx.BOTTOM ,10)
		
		ButtonClose = wx.Button(self, -1, "Close")
		self.Bind(wx.EVT_BUTTON, self.OnCloseMe, ButtonClose)
		ButtonMake = wx.Button(self,-1,"Make")
		self.Bind(wx.EVT_BUTTON,self.OnMake,ButtonMake)
		ButtonClear = wx.Button(self, -1, "Clear")
		self.Bind(wx.EVT_BUTTON, self.OnClear, ButtonClear)
		
		RightSize.Add(BSize,0,wx.EXPAND | wx.RIGHT | wx.LEFT | wx.TOP, 10)
		RightSize.Add(ButtonClear,0,wx.EXPAND |wx.RIGHT | wx.LEFT | wx.TOP, 10)
		RightSize.Add(ButtonMake,0,wx.EXPAND | wx.RIGHT | wx.LEFT | wx.TOP, 10)
		RightSize.Add(ButtonClose,0,wx.EXPAND | wx.RIGHT | wx.LEFT | wx.BOTTOM, 10)
		
		### Main
		MainSize = wx.BoxSizer(wx.HORIZONTAL)
		MainSize.Add(LeftSize, 1,wx.EXPAND)
		MainSize.Add(RightSize, 0,wx.FIXED_MINSIZE)
		
		self.SetSizer(MainSize)
		if checkFlag == True:
			self.Check1.SetValue(True)
			self.OnCheckFixed(None)

	def OnCheckFixed(self, evt):
		self.Canvas.SetFixed(self.Check1.IsChecked())
		self.ChangeWH()
		self.Canvas.OnClearDot()
	def OnTextW(self, evt):
		if self.TextW.GetValue()!="":
			if int(self.TextW.GetValue()) <= 0:
				self.TextW.SetValue('1')
			if int(self.TextW.GetValue()) > self.Canvas.GetClientSize()[0]:
				self.TextW.SetValue(str(self.Canvas.GetClientSize()[0]))
			self.ChangeWH()
	def OnTextH(self, evt):
		if self.TextH.GetValue()!="":
			if int(self.TextH.GetValue()) <= 0:
				self.TextH.SetValue('1')
			if int(self.TextH.GetValue()) > self.Canvas.GetClientSize()[1]:
				self.TextH.SetValue(str(self.Canvas.GetClientSize()[1]))
			self.ChangeWH()
			
	def ChangeWH(self):
		self.Canvas.OnSizeCanvas \
			(None, \
			 int(self.TextW.GetValue()), \
			 int(self.TextH.GetValue()))
	def OnMake(self,evt):
		image = self.Canvas.OnMakeImage()
		self.pil = Image.new('RGB',(image.GetWidth(),image.GetHeight()))
		self.pil.fromstring(image.GetData())
		# Obj
		self.obj.edit_image(self.pil)
		self.OnCloseMe(None)
	def OnClear(self,evt):
		self.Canvas.OnClearDot()
	def OnPlot(self, evt):
		for x in range(self.Canvas.w):
			for y in range(self.Canvas.h):
				if eval(self.TextPlot.GetValue()):
					self.Canvas.OnPlot(x,self.Canvas.h-y-1)
		dc = wx.ClientDC(self.Canvas)
		self.Canvas.OnDrawDot(None,dc)
	def OnCloseMe(self,e):
		setOutput(self.obj,self.frame)
		self.Close(True)
	def OnChangeColor(self,e):
		self.Canvas.SetPlotColor(e.GetColor())
class ImageCanvas(wx.Panel):
	def __init__(self,parent):
		wx.Panel.__init__(self,parent,-1,size=wx.DefaultSize,style=wx.SIMPLE_BORDER)
		
		# fixed pixel or not
		self.fixed = 0
		
		self.LabelWH = None
		self.LabelXY = None
		
		self.dotlist = sets.Set()
		self.dotlistcolor = dict()
		
		self.w = 0
		self.h = 0
		
		self.SetPlotColor('black')
		self.SetBackgroundColour("white")
		
		self.Bind(wx.EVT_LEFT_DOWN,self.OnClick)
		self.Bind(wx.EVT_LEFT_UP,self.OnClick)
		self.Bind(wx.EVT_MOTION,self.OnMove)
		self.Bind(wx.EVT_PAINT,self.OnPaintCanvas)
		self.Bind(wx.EVT_SIZE,self.OnSizeCanvas)
	def SetFixed(self,fixed):
		self.fixed = fixed
	def SetPlotColor(self, plotcolor):
		self.plotcolor = plotcolor
	def OnMakeImage(self):
		self.OnSizeCanvas()
		bmp = wx.EmptyBitmap(self.w, self.h)
		bmpDC = wx.MemoryDC()
		bmpDC.SelectObject(bmp)
		bmpDC.Clear()
		
		if self.fixed == False:
			self.OnDrawDot(None,bmpDC)
		else:
			bmpDC.BeginDrawing()
			for tuple in self.dotlist:
				bmpDC.SetPen(wx.Pen(self.dotlistcolor[tuple]))
				bmpDC.DrawPoint(tuple[0],tuple[1])
			bmpDC.EndDrawing()
		image = bmp.ConvertToImage()
		bmpDC.Clear()
		bmpDC.SelectObject(wx.NullBitmap)
		return image
	def OnSizeCanvas(self,evt=None,w=None,h=None):
		if self.fixed==False:
			self.w = self.GetClientSize()[0]
			self.h = self.GetClientSize()[1]
		else:
			if w != None and h != None:
				self.w = w
				self.h = h
				self.OnClearDot()
		self.LabelWH.SetLabel('w : %d, h : %d' % (self.w,self.h))
	def OnPaintCanvas(self, evt):
		dc = wx.PaintDC(self)
		self.OnDrawDot(evt,dc)
		self.OnDrawLine(dc)
	def OnMove(self, evt):
		if evt.Dragging():
			self.OnClick(evt)
			
		pos = evt.GetPosition()
		self.OnPrintXY(pos)
	def OnPrintXY(self,pos):
		wd = self.GetClientSize()[0] / (self.w)
		hd = self.GetClientSize()[1] / (self.h)
		if wd > hd: wd=hd
		if wd <= 0:  wd=1
			
		x,y = pos.x / wd, pos.y / wd
		self.LabelXY.SetLabel('x : %d, y : %d' % (int(x),int(y)))
	def OnClick(self,evt):
		dc = wx.ClientDC(self)
		self.OnDrawLine(dc)

		pos = evt.GetPosition()
		self.OnPrintXY(pos)
		
		wd = self.GetClientSize()[0] / (self.w)
		hd = self.GetClientSize()[1] / (self.h)
		if wd > hd: wd=hd
		if wd <= 0:  wd=1
			
		x = pos.x / wd
		y = pos.y / wd
		
		length = len(self.dotlist)
		self.dotlist.add((x,y))
		
		if len(self.dotlist) <> length:
			self.dotlistcolor[(x,y)] = self.plotcolor
			dc = wx.ClientDC(self)
			#self.OnDrawDot(None,dc)
			self.OnDrawPoint(None,dc,x,y)
		else:
			color = self.dotlistcolor[(x,y)]
			if color <> self.plotcolor:
				self.dotlistcolor[(x,y)] = self.plotcolor
				dc = wx.ClientDC(self)
				#self.OnDrawDot(None,dc)
				self.OnDrawPoint(None,dc,x,y)	

	def OnPlot(self,x,y):
		self.dotlist.add((x,y))
		self.dotlistcolor[(x,y)] = self.plotcolor
	def OnDrawDot(self,evt,dc):
		dc.BeginDrawing()
		
		if self.fixed == False:
			for tuple in self.dotlist:
				dc.SetPen(wx.Pen(self.dotlistcolor[tuple]))
				dc.DrawPoint(tuple[0],tuple[1])
		else:
			wd = self.GetClientSize()[0] / self.w
			hd = self.GetClientSize()[1] / self.h
			if wd > hd: wd=hd
			for tuple in self.dotlist:
				dc.SetPen(wx.Pen(self.dotlistcolor[tuple]))
				dc.SetBrush(wx.Brush(self.dotlistcolor[tuple]))
				x = tuple[0]
				y = tuple[1]
				if x < self.w and y < self.h:
					if wd > 1:
						dc.DrawRectangle(x*wd + 1,y*wd + 1,wd-1,wd-1)
					else:
						dc.DrawPoint(x,y)
		dc.EndDrawing()
	def OnDrawPoint(self,evt,dc,x,y):
		dc.BeginDrawing()
		if self.fixed == False:
			dc.SetPen(wx.Pen(self.dotlistcolor[(x,y)]))
			dc.DrawPoint(x,y)
		else:
			wd = self.GetClientSize()[0] / self.w
			hd = self.GetClientSize()[1] / self.h
			if wd > hd: wd = hd
			
			dc.SetPen(wx.Pen(self.dotlistcolor[(x,y)]))
			dc.SetBrush(wx.Brush(self.dotlistcolor[(x,y)]))
			
			if x < self.w and y < self.h:
				if wd > 1:
					dc.DrawRectangle(x*wd +1 ,y*wd + 1,wd-1,wd-1)
				else:
					dc.DrawPoint(x,y)
		dc.EndDrawing()	
		self.OnDrawLine(dc)
		
	def OnClearDot(self,evt=None):
		self.dotlist = sets.Set([])
		self.dotlistcolor.clear()
		dc = wx.ClientDC(self)
		dc.Clear()
		self.OnDrawLine(dc)
	def OnDrawLine(self, dc):
		# draw line
		if self.fixed == True:
			dc.BeginDrawing()
			dc.SetPen(wx.Pen('#6666ff'))
			
			wd = self.GetClientSize()[0] / self.w
			hd = self.GetClientSize()[1] / self.h
			if wd > hd: wd = hd
			
			for i in range(self.w + 1):
				dc.DrawLine(i * wd, 0, i * wd, self.h * wd)
			for i in range(self.h + 1):
				dc.DrawLine(0, i * wd, self.w * wd , i * wd)
			dc.EndDrawing()
	