'''
# ----------------------------------------------------------------------------
# Copyright (C) 2014 305engineering <305engineering@gmail.com>
# Original concept by 305engineering.
#
# "THE MODIFIED BEER-WARE LICENSE" (Revision: my own :P):
# <305engineering@gmail.com> wrote this file. As long as you retain this notice you
# can do whatever you want with this stuff (except sell). If we meet some day, 
# and you think this stuff is worth it, you can buy me a beer in return.
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ----------------------------------------------------------------------------
'''


import sys
import os
import re

sys.path.append('/usr/share/inkscape/extensions')
sys.path.append('/Applications/Inkscape.app/Contents/Resources/extensions') 

import subprocess
import math

import inkex
import fablabchemnitz_png
import array


class GcodeExport(inkex.Effect):

######## 	Invoked by _main()
	def __init__(self):
		"""init the effect library and get options from gui"""
		inkex.Effect.__init__(self)
		
		# Image export options
		self.OptionParser.add_option("-d", "--directory",action="store", type="string", dest="directory", default="/home/",help="Directory for files") ####check_dir
		self.OptionParser.add_option("-f", "--filename", action="store", type="string", dest="filename", default="-1.0", help="File name")            
		self.OptionParser.add_option("","--add-numeric-suffix-to-filename", action="store", type="inkbool", dest="add_numeric_suffix_to_filename", default=True,help="Add numeric suffix to filename")            
		self.OptionParser.add_option("","--bg_color",action="store",type="string",dest="bg_color",default="",help="")
		self.OptionParser.add_option("","--resolution",action="store", type="int", dest="resolution", default="5",help="") #Usare il valore su float(xy)/resolution e un case per i DPI dell export
		
		
		# How to convert to grayscale
		self.OptionParser.add_option("","--grayscale_type",action="store", type="int", dest="grayscale_type", default="1",help="") 
		
		# Conversion Mode in Black and White 
		self.OptionParser.add_option("","--conversion_type",action="store", type="int", dest="conversion_type", default="1",help="") 
		
		# Modal Options
		self.OptionParser.add_option("","--BW_Max",action="store", type="int", dest="BW_Max", default="255",help="") 
		self.OptionParser.add_option("","--Laser_Min",action="store", type="int", dest="Laser_Min", default="40",help="") 
		self.OptionParser.add_option("","--Dim_Test_Times",action="store", type="int", dest="Dim_Test_Times", default="3",help="") 
		self.OptionParser.add_option("","--BW_threshold",action="store", type="int", dest="BW_threshold", default="128",help="") 
		self.OptionParser.add_option("","--grayscale_resolution",action="store", type="int", dest="grayscale_resolution", default="1",help="") 
		
		#Black Velocity and Moving
		self.OptionParser.add_option("","--speed_ON",action="store", type="int", dest="speed_ON", default="1200",help="") 

		# Mirror Y
		self.OptionParser.add_option("","--flip_y",action="store", type="inkbool", dest="flip_y", default=False,help="")
		
		# Homing
		self.OptionParser.add_option("","--homing",action="store", type="int", dest="homing", default="4",help="")

		# Commands
		self.OptionParser.add_option("","--laseron", action="store", type="string", dest="laseron", default="M106", help="")
		self.OptionParser.add_option("","--laseroff", action="store", type="string", dest="laseroff", default="M107", help="")
		
		
		# Preview = BN image only
		self.OptionParser.add_option("","--preview_only",action="store", type="inkbool", dest="preview_only", default=False,help="") 

		#inkex.errormsg("BLA BLA BLA Message to display") #DEBUG

		
######## 	Invoked by __init __ ()
########	Here everything is done
	def effect(self):
		

		current_file = self.args[-1]
		bg_color = self.options.bg_color
		
		
		##Implementare check_dir
		
		if (os.path.isdir(self.options.directory)) == True:					
			
			##CODE THAT IS THE DIRECTORY
			#inkex.errormsg("OK") #DEBUG

			
			#I add a suffix to the filename to not overwrite the files
			if self.options.add_numeric_suffix_to_filename :
				dir_list = os.listdir(self.options.directory) #List all the files in the work directory
				temp_name =  self.options.filename
				max_n = 0
				for s in dir_list :
					r = re.match(r"^%s_0*(\d+)%s$"%(re.escape(temp_name),'.png' ), s)
					if r :
						max_n = max(max_n,int(r.group(1)))	
				self.options.filename = temp_name + "_" + ( "0"*(4-len(str(max_n+1))) + str(max_n+1) )


			#Generate file paths to use

			
			suffix = ""
			if self.options.conversion_type == 1:
				suffix = "_BWfix_"+str(self.options.BW_threshold)+"_"
			elif self.options.conversion_type == 2:
				suffix = "_BWrnd_"
			elif self.options.conversion_type == 3:
				suffix = "_H_"
			elif self.options.conversion_type == 4:
				suffix = "_Hrow_"
			elif self.options.conversion_type == 5:
				suffix = "_Hcol_"
			else:
				if self.options.grayscale_resolution == 1:
					suffix = "_Gray_256_"
				elif self.options.grayscale_resolution == 2:
					suffix = "_Gray_128_"
				elif self.options.grayscale_resolution == 4:
					suffix = "_Gray_64_"
				elif self.options.grayscale_resolution == 8:
					suffix = "_Gray_32_"
				elif self.options.grayscale_resolution == 16:
					suffix = "_Gray_16_"
				elif self.options.grayscale_resolution == 32:
					suffix = "_Gray_8_"
				else:
					suffix = "_Gray_"
				
			
			pos_file_png_exported = os.path.join(self.options.directory,self.options.filename+".png") 
			pos_file_png_BW = os.path.join(self.options.directory,self.options.filename+suffix+"preview.png") 
			pos_file_gcode = os.path.join(self.options.directory,self.options.filename+suffix+".gcode") 
			posDimTest_file_gcode = os.path.join(self.options.directory,self.options.filename+suffix+"DimTest.gcode") 			

			#Export the image to PNG
			self.exportPage(pos_file_png_exported,current_file,bg_color)


			
			#TO DO
			#Manipulate the PNG image to generate the Gcode file
			self.PNGtoGcode(pos_file_png_exported,pos_file_png_BW,pos_file_gcode)
			
			if self.options.Dim_Test_Times >= 1:
				self.exportDimensionTest(pos_file_png_exported, pos_file_png_BW, posDimTest_file_gcode)
			
		else:
			inkex.errormsg("Directory does not exist! Please specify existing directory!")
            

            
            
########	EXPORT IMAGE IN PNG		
######## 	Invoked by effect ()
		
	def exportPage(self,pos_file_png_exported,current_file,bg_color):		
		######## CREATING THE FILE PNG ########
		#Create the image inside the folder named "pos_file_png_exported"
		#-d 127 = resolution 127DPI => 5 pixels / mm 1pixel = 0.2mm
		###command="inkscape -C -e \"%s\" -b\"%s\" %s -d 127" % (pos_file_png_exported,bg_color,current_file) 

		if self.options.resolution == 1:
			DPI = 25.4
		elif self.options.resolution == 2:
			DPI = 50.8
		elif self.options.resolution == 5:
			DPI = 127
		else:
			DPI = 254

		command="inkscape -C -e \"%s\" -b\"%s\" %s -d %s" % (pos_file_png_exported,bg_color,current_file,DPI) #Command from command line to export to PNG
					
		p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		return_code = p.wait()
		f = p.stdout
		err = p.stderr

		
########	Create a dimensional test of image
	def exportDimensionTest(self,pos_file_png_exported,pos_file_png_BW,posDimTest_file_gcode):	
		#if self.options.Dim_Test_Times > 0:
			reader = fablabchemnitz_png.Reader(pos_file_png_exported)#PNG files generated
			w, h, pixels, metadata = reader.read_flat()
			file_testgcode = open(posDimTest_file_gcode, 'w')  #Create the dimenstional test file
			file_testgcode.write('; Generated with:\n; "Raster 2 Laser Gcode generator"\n; by 305 Engineering\n; With a remix by VE7FRG\n;\n;\n')
			file_testgcode.write('G21; Set units to millimeters\n')			
			file_testgcode.write('G90; Use absolute coordinates\n')				
			file_testgcode.write('G92; Coordinate Offset\n')

			if self.options.homing == 1:
				file_testgcode.write('G28 X0 Y0; home all axes\n')
				file_testgcode.write('M42 P44 S0; Turn on LEDs\n')
				file_testgcode.write('M42 P64 S0; Turn on VENT Fans\n')
			elif self.options.homing == 2:
				file_testgcode.write('$H; home all axes\n')
			elif self.options.homing == 4:
				file_testgcode.write('G28; home all axes\n')
				file_testgcode.write('G92 X-47 Y-27; Coordinate Offset for CR-10 Mini\n')
				file_testgcode.write('G0 Z100; Set laser head 100mm above surface\n')
			else:
				pass

			file_testgcode.write(self.options.laseron + ' S' + str(self.options.Laser_Min) + '\n')
			file_testgcode.write('; This is the number of width: '+ str(w) + '\n')
			file_testgcode.write('; This is the number of height: '+ str(h) + '\n')
			file_testgcode.write('; This is the number of tests: '+ str(self.options.Dim_Test_Times) + '\n')
			file_testgcode.write('; This is the resolution number '+ str(self.options.resolution) + '\n')
			p=1
			while p <= self.options.Dim_Test_Times:
				file_testgcode.write('G1 X' + str(w / self.options.resolution) + '\n')
				file_testgcode.write('G1 Y' + str(h /  self.options.resolution) + '\n')
				file_testgcode.write('G1 X0\n')
				file_testgcode.write('G1 Y0\n')

				p = p+1
			file_testgcode.write(self.options.laseroff + '\n')
			file_testgcode.write('M42 P44 S255; Turn on LEDs\n')
			file_testgcode.close()
		

########	CREATE IMAGE IN B / W AND THEN GENERATE GCODE
######## 	Richiamata da effect()

	def PNGtoGcode(self,pos_file_png_exported,pos_file_png_BW,pos_file_gcode):
		
		######## CREATE IMAGE IN GRAY SCALE ########
		#I scroll the image and make it a list array

		reader = fablabchemnitz_png.Reader(pos_file_png_exported)#PNG files generated
		
		w, h, pixels, metadata = reader.read_flat()
		
		
		matrice = [[255 for i in range(w)]for j in range(h)]  #List al posto di un array
		

		#I write a new image in 8bit Gray scale
		#Pixel by pixel copy 
		
		if self.options.grayscale_type == 1:
			#0.21R + 0.71G + 0.07B
			for y in range(h): # Y ranges from 0 to h-1
				for x in range(w): # X varies from 0 to w-1
					pixel_position = (x + y * w)*4 if metadata['alpha'] else (x + y * w)*3
					matrice[y][x] = int(pixels[pixel_position]*0.21 + pixels[(pixel_position+1)]*0.71 + pixels[(pixel_position+2)]*0.07)
		
		elif self.options.grayscale_type == 2:
			#(R+G+B)/3
			for y in range(h): #Y ranges from 0 to h-1
				for x in range(w): # X varies from 0 to w-1
					pixel_position = (x + y * w)*4 if metadata['alpha'] else (x + y * w)*3
					matrice[y][x] = int((pixels[pixel_position] + pixels[(pixel_position+1)]+ pixels[(pixel_position+2)]) / 3 )		

		elif self.options.grayscale_type == 3:
			#R
			for y in range(h): # Y ranges from 0 to h-1
				for x in range(w): # X varies from 0 to w-1
					pixel_position = (x + y * w)*4 if metadata['alpha'] else (x + y * w)*3
					matrice[y][x] = int(pixels[pixel_position])			

		elif self.options.grayscale_type == 4:
			#G
			for y in range(h): # Y ranges from 0 to h-1
				for x in range(w): # X varies from 0 to w-1
					pixel_position = (x + y * w)*4 if metadata['alpha'] else (x + y * w)*3
					matrice[y][x] = int(pixels[(pixel_position+1)])	
		
		elif self.options.grayscale_type == 5:
			#B
			for y in range(h): # Y ranges from 0 to h-1
				for x in range(w): # X varies from 0 to w-1
					pixel_position = (x + y * w)*4 if metadata['alpha'] else (x + y * w)*3
					matrice[y][x] = int(pixels[(pixel_position+2)])				
			
		elif self.options.grayscale_type == 6:
			#Max Color
			for y in range(h): # Y ranges from 0 to h-1
				for x in range(w): # X varies from 0 to w-1
					pixel_position = (x + y * w)*4 if metadata['alpha'] else (x + y * w)*3
					list_RGB = pixels[pixel_position] , pixels[(pixel_position+1)] , pixels[(pixel_position+2)]
					matrice[y][x] = int(max(list_RGB))				

		else:
			#Min Color
			for y in range(h): # Y ranges from 0 to h-1
				for x in range(w): # X varies from 0 to w-1
					pixel_position = (x + y * w)*4 if metadata['alpha'] else (x + y * w)*3
					list_RGB = pixels[pixel_position] , pixels[(pixel_position+1)] , pixels[(pixel_position+2)]
					matrice[y][x] = int(min(list_RGB))	
		

		####Master matrix contains the grayscale image


		######## GENERATE BLACK AND BLACK IMAGE ########
		#Scorro matrice and generate matrice_BN
		B=255
		N=0 
		
		matrice_BN = [[255 for i in range(w)]for j in range(h)]
		
		
		if self.options.conversion_type == 1:
			#B/W fixed threshold
			soglia = self.options.BW_threshold
			for y in range(h): 
				for x in range(w):
					if matrice[y][x] >= soglia :
						matrice_BN[y][x] = B
					else:
						matrice_BN[y][x] = N
	
			
		elif self.options.conversion_type == 2:
			#B/W random threshold
			from random import randint
			for y in range(h): 
				for x in range(w): 
					soglia = randint(20,235)
					if matrice[y][x] >= soglia :
						matrice_BN[y][x] = B
					else:
						matrice_BN[y][x] = N
			
			
		elif self.options.conversion_type == 3:
			#Halftone
			Step1 = [[B,B,B,B,B],[B,B,B,B,B],[B,B,N,B,B],[B,B,B,B,B],[B,B,B,B,B]]
			Step2 = [[B,B,B,B,B],[B,B,N,B,B],[B,N,N,N,B],[B,B,N,B,B],[B,B,B,B,B]]
			Step3 = [[B,B,N,B,B],[B,N,N,N,B],[N,N,N,N,N],[B,N,N,N,B],[B,B,N,B,B]]
			Step4 = [[B,N,N,N,B],[N,N,N,N,N],[N,N,N,N,N],[N,N,N,N,N],[B,N,N,N,B]]
			
			for y in range(h/5): 
				for x in range(w/5): 
					media = 0
					for y2 in range(5):
						for x2 in range(5):
							media +=  matrice[y*5+y2][x*5+x2]
					media = media /25
					for y3 in range(5):
						for x3 in range(5):
							if media >= 250 and media <= 255:
								matrice_BN[y*5+y3][x*5+x3] = 	B	
							if media >= 190 and media < 250:
								matrice_BN[y*5+y3][x*5+x3] =	Step1[y3][x3]
							if media >= 130 and media < 190:
								matrice_BN[y*5+y3][x*5+x3] =	Step2[y3][x3]
							if media >= 70 and media < 130:
								matrice_BN[y*5+y3][x*5+x3] =	Step3[y3][x3]
							if media >= 10 and media < 70:
								matrice_BN[y*5+y3][x*5+x3] =	Step4[y3][x3]		
							if media >= 0 and media < 10:
								matrice_BN[y*5+y3][x*5+x3] = N


		elif self.options.conversion_type == 4:
			#Halftone row
			Step1r = [B,B,N,B,B]
			Step2r = [B,N,N,B,B]
			Step3r = [B,N,N,N,B]
			Step4r = [N,N,N,N,B]

			for y in range(h): 
				for x in range(w/5): 
					media = 0
					for x2 in range(5):
						media +=  matrice[y][x*5+x2]
					media = media /5
					for x3 in range(5):
						if media >= 250 and media <= 255:
							matrice_BN[y][x*5+x3] = 	B
						if media >= 190 and media < 250:
							matrice_BN[y][x*5+x3] =	Step1r[x3]
						if media >= 130 and media < 190:
							matrice_BN[y][x*5+x3] =	Step2r[x3]
						if media >= 70 and media < 130:
							matrice_BN[y][x*5+x3] =	Step3r[x3]
						if media >= 10 and media < 70:
							matrice_BN[y][x*5+x3] =	Step4r[x3]		
						if media >= 0 and media < 10:
							matrice_BN[y][x*5+x3] = N			


		elif self.options.conversion_type == 5:
			#Halftone column
			Step1c = [B,B,N,B,B]
			Step2c = [B,N,N,B,B]
			Step3c = [B,N,N,N,B]
			Step4c = [N,N,N,N,B]

			for y in range(h/5):
				for x in range(w):
					media = 0
					for y2 in range(5):
						media +=  matrice[y*5+y2][x]
					media = media /5
					for y3 in range(5):
						if media >= 250 and media <= 255:
							matrice_BN[y*5+y3][x] = 	B
						if media >= 190 and media < 250:
							matrice_BN[y*5+y3][x] =	Step1c[y3]
						if media >= 130 and media < 190:
							matrice_BN[y*5+y3][x] =	Step2c[y3]
						if media >= 70 and media < 130:
							matrice_BN[y*5+y3][x] =	Step3c[y3]
						if media >= 10 and media < 70:
							matrice_BN[y*5+y3][x] =	Step4c[y3]		
						if media >= 0 and media < 10:
							matrice_BN[y*5+y3][x] = N			
			
		else:
			#Grayscale
			if self.options.grayscale_resolution == 1:
				matrice_BN = matrice
			else:
				for y in range(h): 
					for x in range(w): 
						if matrice[y][x] <= 1:
							matrice_BN[y][x] == 0
							
						if matrice[y][x] >= 254:
							matrice_BN[y][x] == 255
						
						if matrice[y][x] > 1 and matrice[y][x] <254:
							matrice_BN[y][x] = ( matrice[y][x] // self.options.grayscale_resolution ) * self.options.grayscale_resolution
						
			
			
		####Ora matrice_BN contiene l'immagine in Bianco (255) e Nero (0)


		#### SAVE BLACK AND BLACK IMAGE ####
		file_img_BN = open(pos_file_png_BW, 'wb') #Create the file
		Costruttore_img = fablabchemnitz_png.Writer(w, h, greyscale=True, bitdepth=8) #Setting the image file
		Costruttore_img.write(file_img_BN, matrice_BN) #Image file builder
		file_img_BN.close()	#Close the file


		#### GENERO IL FILE GCODE ####	
		if self.options.preview_only == False: #Genero Gcode solo se devo
		
			if self.options.flip_y == False: #Inverto asse Y solo se flip_y = False     
				#-> coordinate Cartesiane (False) Coordinate "informatiche" (True)
				matrice_BN.reverse()				

			
			Laser_ON = False
			F_G01 = self.options.speed_ON
			Scala = self.options.resolution
			Scaler = float(self.options.BW_Max)/255

			file_gcode = open(pos_file_gcode, 'w')  #Create the file
			
			#Configurazioni iniziali standard Gcode
			file_gcode.write('; Generated with:\n; "Raster 2 Laser Gcode generator"\n; by 305 Engineering\n; With a remix by VE7FRG\n;\n;\n')
			#HOMING

			file_gcode.write('G21; Set units to millimeters\n')
			file_gcode.write('G90; Use absolute coordinates\n')
			file_gcode.write('G92; Coordinate Offset\n')
			if self.options.homing == 1:
				file_gcode.write('G28; home all axes\n')
				file_gcode.write('M42 P44 S0; Turn on LEDs\n')
				file_gcode.write('M42 P64 S0; Turn on VENT Fans\n')
			elif self.options.homing == 2:
				file_gcode.write('$H; home all axes\n')
			elif self.options.homing == 4:
				file_gcode.write('G28 X0 Y0; home all axes\n')
				file_gcode.write('G92 X-47 Y-27; Coordinate Offset for CR-10 Mini\n')
				file_gcode.write('G0 Z100; Set laser head 100mm above surface\n')
			else:
				pass

#			file_gcode.write('G90; Use absolute coordinates\n')
#			file_gcode.write('G92; Coordinate Offset\n')

			#Creazione del Gcode
			
			#allargo la matrice per lavorare su tutta l'immagine
			for y in range(h):
				matrice_BN[y].append(B)
			w = w+1
			
			if self.options.conversion_type != 6:
				for y in range(h):
					if y % 2 == 0 :
						for x in range(w):
							if matrice_BN[y][x] == N :
								if Laser_ON == False :
									#file_gcode.write('G00 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) + ' F' + str(F_G00) + '\n')
									file_gcode.write('G00 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) + '\n') #tolto il Feed sul G00
									file_gcode.write(self.options.laseron + '\n')			
									Laser_ON = True
								if  Laser_ON == True :   #DEVO evitare di uscire dalla matrice
									if x == w-1 :
										file_gcode.write('G1 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) +' F' + str(F_G01) + '\n')
										file_gcode.write(self.options.laseroff + '\n')
										Laser_ON = False
									else: 
										if matrice_BN[y][x+1] != N :
											file_gcode.write('G1 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) + ' F' + str(F_G01) +'\n')
											file_gcode.write(self.options.laseroff + '\n')
											Laser_ON = False
					else:
						for x in reversed(range(w)):
							if matrice_BN[y][x] == N :
								if Laser_ON == False :
									#file_gcode.write('G00 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) + ' F' + str(F_G00) + '\n')
									file_gcode.write('G00 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) + '\n') #tolto il Feed sul G00
									file_gcode.write(self.options.laseron + '\n')			
									Laser_ON = True
								if  Laser_ON == True :   #DEVO evitare di uscire dalla matrice
									if x == 0 :
										file_gcode.write('G1 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) +' F' + str(F_G01) + '\n')
										file_gcode.write(self.options.laseroff + '\n')
										Laser_ON = False
									else: 
										if matrice_BN[y][x-1] != N :
											file_gcode.write('G1 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) + ' F' + str(F_G01) +'\n')
											file_gcode.write(self.options.laseroff + '\n')
											Laser_ON = False				

			else: ##SCALA DI GRIGI
				for y in range(h):
					if y % 2 == 0 :
						for x in range(w):
							if matrice_BN[y][x] != B :
								if Laser_ON == False :
									file_gcode.write('G00 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) +'\n')
									file_gcode.write(self.options.laseron + ' '+ ' S' + str(int(round(float((255 - matrice_BN[y][x])*Scaler)))) +'\n')
									Laser_ON = True
									
								if  Laser_ON == True :   #DEVO evitare di uscire dalla matrice
									if x == w-1 : #controllo fine riga
										file_gcode.write('G1 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) +' F' + str(F_G01) + '\n')
										file_gcode.write(self.options.laseroff + '\n')
										Laser_ON = False
										
									else: 
										if matrice_BN[y][x+1] == B :
											file_gcode.write('G1 X' + str(float(x+1)/Scala) + ' Y' + str(float(y)/Scala) + ' F' + str(F_G01) +'\n')
											file_gcode.write(self.options.laseroff + '\n')
											Laser_ON = False
											
										elif matrice_BN[y][x] != matrice_BN[y][x+1] :
											file_gcode.write('G1 X' + str(float(x+1)/Scala) + ' Y' + str(float(y)/Scala) + ' F' + str(F_G01) +'\n')
											file_gcode.write(self.options.laseron + ' '+ ' S' + str(int(round(float((255 - matrice_BN[y][x])*Scaler)))) +'\n')									

					
					else:
						for x in reversed(range(w)):
							if matrice_BN[y][x] != B :
								if Laser_ON == False :
									file_gcode.write('G00 X' + str(float(x+1)/Scala) + ' Y' + str(float(y)/Scala) +'\n')
									#file_gcode.write(self.options.laseron + ' '+ ' S' + str(self.options.BW_Max - matrice_BN[y][x]) +'\n')
									file_gcode.write(self.options.laseron + ' '+ ' S' + str(int(round(float((255 - matrice_BN[y][x])*Scaler)))) +'\n')
									Laser_ON = True
									
								if  Laser_ON == True :   #DEVO evitare di uscire dalla matrice
									if x == 0 : #controllo fine riga ritorno
										file_gcode.write('G1 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) +' F' + str(F_G01) + '\n')
										file_gcode.write(self.options.laseroff + '\n')
										Laser_ON = False
										
									else: 
										if matrice_BN[y][x-1] == B :
											file_gcode.write('G1 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) + ' F' + str(F_G01) +'\n')
											file_gcode.write(self.options.laseroff + '\n')
											Laser_ON = False
											
										elif  matrice_BN[y][x] != matrice_BN[y][x-1] :
											file_gcode.write('G1 X' + str(float(x)/Scala) + ' Y' + str(float(y)/Scala) + ' F' + str(F_G01) +'\n')
											#file_gcode.write(self.options.laseron + ' '+ ' S' + str(self.options.BW_Max - matrice_BN[y][x-1]) +'\n')
											file_gcode.write(self.options.laseron + ' '+ ' S' + str(int(round(float((255 - matrice_BN[y][x])*Scaler)))) +'\n')

			
			
			#Configurazioni finali standard Gcode
			file_gcode.write('G00 X0 Y0; home\n')
			#HOMING
			if self.options.homing == 1:
				file_gcode.write('G28 X0 Y0; home all axes\n')
				file_gcode.write('M42 P44 S255; Turn on LEDs\n')
				file_gcode.write('M42 P64 S255; Turn on VENT Fans\n')
			elif self.options.homing == 2:
				file_gcode.write('$H; home all axes\n')
			else:
				pass
			
			file_gcode.close() #Chiudo il file




######## 	######## 	######## 	######## 	######## 	######## 	######## 	######## 	######## 	


def _main():
	e=GcodeExport()
	e.affect()
	
	exit()

if __name__=="__main__":
	_main()







