""" do file io """

# pylint: disable=invalid-name

from __future__ import annotations
import json
from typing import Any
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement
from os.path import exists
from shlex import split
from math import ceil
from re import findall
from defusedxml.ElementTree import parse
from defusedxml.minidom import parseString
from metprint import LogType, Logger, FHFormatter
from colormath.color_objects import ColorBase, sRGBColor, CMYKColor, LabColor
import yaml
import tomlkit
from PIL import Image, ImageDraw
import swatch

from colourswatch.colourswatch import ColourSwatch, Colour
from colourswatch.GimpGplPalette import GimpGplPalette

def prettify(elem: Element, indent: str="\t", doctype: str="<?xml version=\"1.0\" encoding=\"utf-8\"?>"):
	"""Return a pretty-printed XML string for the Element.  """
	rough_string = ElementTree.tostring(elem, 'utf-8')
	reparsed = parseString(rough_string)
	reparsed = reparsed.toprettyxml(indent=indent).split("\n")[1:]
	reparsed.insert(0, doctype)
	return "\n".join(reparsed)

def extNotRecognised(fileName: str):
	""" Output the file extension not recognised error """
	exts = ["gpl", "yaml", "colors", "spl", "skp", "soc", "txt", "acbl", "xml",
	"pal", "hpl", "toml", "json", "ase", "png", "jpg", "webp", "svg"]
	Logger(FHFormatter()).logPrint("File extension is not recognised for file: " +
	fileName + "! Must be " + "one of \"" + ", \"".join(exts) + "\"", LogType.ERROR)

def openColourSwatch(file: str) -> ColourSwatch:
	"""Open a colour swatch file into a layer image object
	Args:
		file (str): path/ filename
	Returns:
		ColourSwatch: a colour swatch object
	"""
	functionMap = {"gpl": openSwatch_GPL, "yaml": openSwatch_YAML,
	"colors": openSwatch_COLOR, "spl": openSwatch_SPL, "skp": openSwatch_SKP,
	"soc": openSwatch_SOC, "txt": openSwatch_TXT, "acbl": openSwatch_ACBL,
	"xml": openSwatch_XML, "pal": openSwatch_CDPAL, "hpl": openSwatch_HPL,
	"toml": openSwatch_TOML, "json": openSwatch_JSON, "png": openSwatch_PNG,
	"jpg": openSwatch_IMAGE, "webp": openSwatch_IMAGE, "ase": openSwatch_ASE,
	"svg": openSwatch_SVG}
	if not exists(file):
		Logger(FHFormatter()).logPrint(file + " does not exist", LogType.ERROR)
		raise FileExistsError
	fileExt = file.split(".")[-1].lower()
	if fileExt not in functionMap:
		extNotRecognised(file)
		raise ValueError
	return functionMap[fileExt](file)

def saveColourSwatch(fileName: str, colourSwatch: ColourSwatch):
	"""Save a colour swatch to a file
	Args:
		fileName (str): path/ filename
		colourSwatch (ColourSwatch): the colour swatch to save
	"""
	functionMap = {"gpl": saveSwatch_GPL, "yaml": saveSwatch_YAML,
	"colors": saveSwatch_COLOR, "spl": saveSwatch_SPL, "skp": saveSwatch_SKP,
	"soc": saveSwatch_SOC, "txt": saveSwatch_TXT, "acbl": saveSwatch_ACBL,
	"xml": saveSwatch_XML, "pal": saveSwatch_CDPAL, "hpl": saveSwatch_HPL,
	"toml": saveSwatch_TOML, "json": saveSwatch_JSON, "png": saveSwatch_IMAGE,
	"jpg": saveSwatch_IMAGE, "webp": saveSwatch_IMAGE, "ase": saveSwatch_ASE,
	"svg": saveSwatch_SVG}
	fileExt = fileName.split(".")[-1].lower()
	if fileExt not in functionMap:
		extNotRecognised(fileName)
		raise ValueError
	return functionMap[fileExt](fileName, colourSwatch)


def getColourFromLine(line: str, lineno: int, colourSpaceSize: int=3,
colourSpace: ColorBase=sRGBColor, divider: int=255):
	""" getColourFromLine """
	parts = line.split(None)
	return Colour(" ".join(parts[colourSpaceSize:]) if len(parts) > colourSpaceSize
	else "colour{}".format(lineno),
	colour=colourSpace(*[float(col)/divider for col in parts[:colourSpaceSize]]),
	nameNull=len(parts) <= colourSpaceSize)


def getSwatchFromFileName(file: str, colours: list[Colour]):
	""" getSwatchFromFileName """
	return ColourSwatch(file.replace("\\", "/").split("/")[-1].split(".")[0], colours)

def getWriteOutColour(colour: list[Any], convertType: type=int, multiplier: int=255) -> list[Any]:
	""" getWriteOutColour """
	return [convertType(col * multiplier) for col in colour]


### GPL ###
def openSwatch_GPL(file: str):
	""" Open a .GPL into a colour swatch """
	project = GimpGplPalette(file)
	colours = []
	for index, colour in enumerate(project.colors):
		colours.append(Colour(project.colorNames[index] if
		project.colorNames[index] is not None else "colour{}".format(index),
		colour=sRGBColor(colour[0], colour[1], colour[2], True),
		nameNull=project.colorNames[index] is None))
	return ColourSwatch(project.name, colours=colours)

def saveSwatch_GPL(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .GPL """
	project = GimpGplPalette()
	project.name = colourSwatch.name
	project.colors = [getWriteOutColour(colour.toRGB().get_value_tuple())
	for colour in colourSwatch.colours]
	project.colorNames = [colour.name if not colour.nameNull else None
	for colour in colourSwatch.colours]
	project.save(fileName)


### YAML ###
def openSwatch_YAML(file: str) -> ColourSwatch:
	""" Open a .YAML into a colour swatch """
	with open(file) as fileData:
		project = yaml.safe_load(fileData.read())
		swatchName = project.pop("scheme") if "scheme" in project else project.pop("name")
		swatchAuthor = project.pop("author") if "author" in project else None
	return ColourSwatch(swatchName, colours=[Colour(key,
	colour=sRGBColor(int(project[key][0:2], 16), int(project[key][2:4], 16),
	int(project[key][4:6], 16), True))
	for key in project], author=swatchAuthor)

def saveSwatch_YAML(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .YAML """
	with open(fileName, "w") as fileData:
		yamldict = {"scheme": colourSwatch.name, "author": colourSwatch.author}
		for colour in colourSwatch.colours:
			yamldict[colour.name] = "".join(colour.getRGB255Hex())
		fileData.write(yaml.safe_dump(yamldict))


### JSON ###
def openSwatch_JSON(file: str) -> ColourSwatch:
	""" Open a .JSON into a colour swatch """
	with open(file) as fileData:
		project = json.loads(fileData.read())
		swatchName = project.pop("scheme") if "scheme" in project else project.pop("name")
		swatchAuthor = project.pop("author") if "author" in project else None
	return ColourSwatch(swatchName, colours=[Colour(key,
	colour=sRGBColor(int(project[key][0:2], 16), int(project[key][2:4], 16),
	int(project[key][4:6], 16), True))
	for key in project], author=swatchAuthor)

def saveSwatch_JSON(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .JSON """
	with open(fileName, "w") as fileData:
		jsondict = {"scheme": colourSwatch.name, "author": colourSwatch.author}
		for colour in colourSwatch.colours:
			jsondict[colour.name] = "".join(colour.getRGB255Hex())
		fileData.write(json.dumps(jsondict, indent="\t"))


### TOML ###
def openSwatch_TOML(file: str) -> ColourSwatch:
	""" Open a .TOML into a colour swatch """
	with open(file) as fileData:
		project = tomlkit.loads(fileData.read())
		swatchName = project.pop("scheme") if "scheme" in project else project.pop("name")
		swatchAuthor = project.pop("author") if "author" in project else None
	return ColourSwatch(swatchName, colours=[Colour(key,
	colour=sRGBColor(int(project[key][0:2], 16), int(project[key][2:4], 16),
	int(project[key][4:6], 16), True))
	for key in project], author=swatchAuthor)

def saveSwatch_TOML(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .TOML """
	with open(fileName, "w") as fileData:
		tomldict = {"scheme": colourSwatch.name, "author": colourSwatch.author}
		for colour in colourSwatch.colours:
			tomldict[colour.name] = "".join(colour.getRGB255Hex())
		fileData.write(tomlkit.dumps(tomldict))


### COLOR ###
def openSwatch_COLOR(file: str) -> ColourSwatch:
	""" Open a .COLOR into a colour swatch """
	with open(file) as fileData:
		colours = []
		for lineno, line in enumerate(fileData.readlines()[1:]):
			colours.append(getColourFromLine(line, lineno))
	return getSwatchFromFileName(file, colours)


def saveSwatch_COLOR(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .COLOR """
	with open(fileName, "w") as fileData:
		fileData.write("KDE RGB Palette\n" + "\n".join([" ".join([str(col) for col in colour.getRGB255()]
		) + "\t{}".format(colour.name)	for colour in colourSwatch.colours]) + "\n")


### SPL ###
def openSwatch_SPL(file: str) -> ColourSwatch:
	""" Open a .SPL into a colour swatch """
	with open(file) as fileData:
		colours = []
		for lineno, line in enumerate(fileData.readlines()[1:]):
			colours.append(getColourFromLine(line, lineno, divider=1))
	return getSwatchFromFileName(file, colours)

def saveSwatch_SPL(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .SPL """
	with open(fileName, "w") as fileData:
		fileData.write("##Sketch RGBPalette 0\n" + "\n".join([" ".join(
			["{:.6f}".format(col) for col in getWriteOutColour(colour.toRGB().get_value_tuple(), float, 1)]
			) + "\t{}".format(colour.name)	for colour in colourSwatch.colours]) + "\n")


### SKP ###
def openSwatch_SKP(file: str) -> ColourSwatch:
	""" Open a .SKP into a colour swatch """
	with open(file) as fileData:
		xmlrep = parse(fileData).getroot()
		cType = xmlrep[0].attrib["type"]
		colours = []
		for colour in xmlrep[1:]:
			cName = colour.attrib["name"]
			if cType == "CMYK":
				cColour = CMYKColor(float(colour.attrib["c"]), float(colour.attrib["m"]),
				float(colour.attrib["y"]), float(colour.attrib["k"]))
			else:
				cColour = sRGBColor(float(colour.attrib["r"]), float(colour.attrib["g"]),
				float(colour.attrib["b"]))
			colours.append(Colour(cName, cColour))
	return ColourSwatch(xmlrep[0].attrib["name"], colours)


def saveSwatch_SKP(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .SKP """
	with open(fileName, "w") as fileData:
		root = Element("palette")
		SubElement(root, "description", {"type": "CMYK", "name": colourSwatch.name})
		for colour in colourSwatch.colours:
			c, m, y, k = getWriteOutColour(colour.toCMYK().get_value_tuple(), float, 1)
			SubElement(root, "color", {"c": str(c), "m": str(m), "y": str(y),
			"k": str(k), "name": colour.name})
		fileData.write(prettify(root))


### SOC ###
def openSwatch_SOC(file: str) -> ColourSwatch:
	""" Open a .SOC into a colour swatch """
	with open(file) as fileData:
		xmlrep = parse(fileData).getroot()
		colours = []
		for colour in xmlrep:
			cName = colour.attrib["{http://openoffice.org/2000/drawing}name"]
			col = colour.attrib["{http://openoffice.org/2000/drawing}color"][1:]
			cColour = sRGBColor(int(col[0:2], 16), int(col[2:4], 16), int(col[4:6], 16), True)
			colours.append(Colour(cName, cColour))
	return getSwatchFromFileName(file, colours)


def saveSwatch_SOC(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .SOC """
	with open(fileName, "w") as fileData:
		root = Element("office_color_table")
		for colour in colourSwatch.colours:
			SubElement(root, "draw_color", {"draw_name": colour.name, "draw_color":
			"#" + "".join(["{:02x}".format(col) for col in
			getWriteOutColour(colour.toRGB().get_value_tuple())])})
		fileData.write(prettify(root, indent=" ",
		doctype="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n").replace("<office_color_table>",
		"<office:color-table xmlns:office=\"http://openoffice.org/2000/office\" " +
		"xmlns:style=\"http://openoffice.org/2000/style\" " +
		"xmlns:text=\"http://openoffice.org/2000/text\" " +
		"xmlns:table=\"http://openoffice.org/2000/table\" " +
		"xmlns:draw=\"http://openoffice.org/2000/drawing\" " +
		"xmlns:fo=\"http://www.w3.org/1999/XSL/Format\" " +
		"xmlns:xlink=\"http://www.w3.org/1999/xlink\" " +
		"xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " +
		"xmlns:meta=\"http://openoffice.org/2000/meta\" " +
		"xmlns:number=\"http://openoffice.org/2000/datastyle\" " +
		"xmlns:svg=\"http://www.w3.org/2000/svg\" " +
		"xmlns:chart=\"http://openoffice.org/2000/chart\" " +
		"xmlns:dr3d=\"http://openoffice.org/2000/dr3d\" " +
		"xmlns:math=\"http://www.w3.org/1998/Math/MathML\" " +
		"xmlns:form=\"http://openoffice.org/2000/form\" " +
		"xmlns:script=\"http://openoffice.org/2000/script\">").replace("office_color_table",
		"office:color-table").replace("draw_color", "draw:color").replace("draw_name", "draw:name"))


### TXT ###
def openSwatch_TXT(file: str) -> ColourSwatch:
	""" Open a .TXT into a colour swatch """
	with open(file) as fileData:
		colours = []
		for lineno, line in enumerate(fileData.readlines()):
			if line[0] != ";":
				colours.append(Colour("colour{}".format(lineno),
				colour=sRGBColor(int(line[0:2], 16), int(line[2:4], 16),
				int(line[4:6], 16), True), nameNull=True, alpha=int(line[6:8], 16)/255))
	return getSwatchFromFileName(file, colours)

def saveSwatch_TXT(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .TXT """
	with open(fileName, "w") as fileData:
		fileData.write("; paint.net Palette File\n; Lines that start with a " +
		"semicolon are comments\n; Colors are written as 8-digit hexadecimal " +
		"numbers: aarrggbb\n; For example, this would specify green: FF00FF00\n; " +
		"The alpha ('aa') value specifies how transparent a color is. FF is " +
		"fully opaque, 00 is fully transparent.\n; A palette must consist of " +
		"ninety six (96) colors. If there are less than this, the remaining " +
		"color\n; slots will be set to white (FFFFFFFF). If there are more, " +
		"then the remaining colors will be ignored.\n" + "\n".join(
			["".join(colour.getRGB255Hex(True)) +
				"{:02X}".format(int(colour.alpha*255)) for colour in colourSwatch.colours]) + "\n")


### ACBL ###
def openSwatch_ACBL(file: str) -> ColourSwatch:
	""" Open a .ACBL into a colour swatch """
	with open(file) as fileData:
		xmlrep = parse(fileData).getroot()
		cType = xmlrep[1][0].attrib["ColorSpace"]
		colours = []
		for colour in xmlrep[2]:
			cName = colour.attrib["N"]
			cRawColour = [float(col) for col in colour[0].text.split(None)]
			if cType == "CMYK":
				cColour = CMYKColor(*cRawColour)
			elif cType == "RGB":
				cColour = sRGBColor(*cRawColour)
			else:
				cColour = LabColor(*cRawColour)
			colours.append(Colour(cName, cColour))
	return getSwatchFromFileName(file, colours)

def saveSwatch_ACBL(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .ACBL """
	raise NotImplementedError


### XML ###
def openSwatch_XML(file: str) -> ColourSwatch:
	""" Open a .XML into a colour swatch """
	with open(file) as fileData:
		xmlrep = parse(fileData).getroot()
		colours = []
		for colour in xmlrep:
			cName = colour.attrib["NAME"]
			col = colour.attrib["RGB"][1:] if "RGB" in colour.attrib else colour.attrib["CMYK"][1:]
			cColour = sRGBColor(int(col[0:2], 16), int(col[2:4], 16), int(col[4:6], 16), True
			) if "RGB" in colour.attrib else CMYKColor(
			int(col[0:2], 16)/255, int(col[2:4], 16)/255,
			int(col[4:6], 16)/255, int(col[6:8], 16)/255)
			colours.append(Colour(cName, cColour))
	return ColourSwatch(xmlrep.attrib["Name"], colours)

def saveSwatch_XML(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .XML """
	with open(fileName, "w") as fileData:
		root = Element("SCRIBUSCOLORS", {"Name": colourSwatch.name})
		for colour in colourSwatch.colours:
			SubElement(root, "COLOR", {"Spot": "0", "Register": "0",
			"NAME": colour.name, "RGB": "#" + "".join(["{:02x}".format(col
			) for col in getWriteOutColour(colour.toRGB().get_value_tuple())])})
		fileData.write(prettify(root, indent=" ", doctype="<?xml version=\"1.0\" encoding=\"UTF-8\"?>"))


### PaintShopPro PAL ###
def openSwatch_PSPPAL(file: str) -> ColourSwatch:
	""" Open a PaintShopPro .PAL into a colour swatch """
	with open(file) as fileData:
		colours = []
		for lineno, line in enumerate(fileData.readlines()[3:]):
			colours.append(getColourFromLine(line, lineno))
	return getSwatchFromFileName(file, colours)

def saveSwatch_PSPPAL(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as PaintShopPro .PAL """
	with open(fileName, "w") as fileData:
		fileData.write("JASC-PAL\n0100\n{}\n".format(len(colourSwatch.colours)) + "\n".join([" ".join(
			["{}".format(col) for col in getWriteOutColour(colour.toRGB().get_value_tuple())]
			) for colour in colourSwatch.colours]) + "\n")


### CorelDraw PAL ###
def openSwatch_CDPAL(file: str) -> ColourSwatch:
	""" Open a CorelDraw .PAL into a colour swatch """
	with open(file) as fileData:
		if fileData.readlines()[0].strip() == "JASC-PAL":
			return openSwatch_PSPPAL(file)
	with open(file) as fileData:
		colours = []
		for line in fileData.readlines():
			parts = split(line)
			colours.append(Colour(parts[0],	colour=CMYKColor(*[float(col)/100 for col in parts[1:5]])))
	return getSwatchFromFileName(file, colours)

def saveSwatch_CDPAL(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as CorelDraw .PAL """
	for colour in colourSwatch.colours:
		if colour.nameNull:
			return saveSwatch_PSPPAL(fileName, colourSwatch)
	with open(fileName, "w") as fileData:
		fileData.write("\n".join(["\"{}\"  ".format(colour.name) + "  ".join(
			["{:>3}".format(col) for col in
			getWriteOutColour(colour.toCMYK().get_value_tuple(), int, 100)])
			for colour in colourSwatch.colours]) + "\n")
	return True


### HPL ###
def openSwatch_HPL(file: str) -> ColourSwatch:
	""" Open a .HPL into a colour swatch """
	with open(file) as fileData:
		colours = []
		for lineno, line in enumerate(fileData.readlines()[3:]):
			colours.append(getColourFromLine(line, lineno))
	return getSwatchFromFileName(file, colours)

def saveSwatch_HPL(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .HPL """
	with open(fileName, "w") as fileData:
		fileData.write("Palette\nVersion 4.0\n\n" + "\n".join([" ".join(
			["{}".format(col) for col in getWriteOutColour(colour.toRGB().get_value_tuple())]
			) for colour in colourSwatch.colours]) + "\n")


### ASE ###
def openSwatch_ASE(file: str) -> ColourSwatch:
	""" Open an .ase into a list of colour swatches """
	project = swatch.parse(file)
	swatches = []
	for swtch in project:
		colours = []
		for colour in swtch["swatches"]:
			if colour["data"]["mode"] == "LAB":
				col = LabColor(*colour["data"]["values"])
			elif colour["data"]["mode"] == "RGB":
				col = sRGBColor(*colour["data"]["values"])
			elif colour["data"]["mode"] == "CMYK":
				col = CMYKColor(*colour["data"]["values"])
			else:
				col = sRGBColor(colour["data"]["values"][0], colour["data"]["values"][0],
				colour["data"]["values"][0])
			colours.append(Colour(colour["name"], colour=col))
		swatches.append(ColourSwatch(swtch["name"], colours))
	return swatches

def saveSwatch_ASE(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .ase """
	raise NotImplementedError


### IMAGE ###
def openSwatch_PNG(file: str) -> ColourSwatch:
	"""Open a .png into a colour swatch """
	colours = []
	project = Image.open(file).convert("RGB")
	seen = set()
	pixels = list(project.getdata())
	rawColours = [x for x in pixels if x not in seen and not seen.add(x)]
	for rCol in rawColours:
		colours.append(Colour("colour{}".format(len(colours)),
		colour=sRGBColor(rCol[0], rCol[1], rCol[2], True),
		nameNull=True))
	return getSwatchFromFileName(file, colours)

def openSwatch_IMAGE(file: str) -> ColourSwatch:
	""" open .jpg, .webp """
	# Colours should be 16x16 px on a canvas with size 256x(16*ceil(colours/16)
	colours = []
	project = Image.open(file).convert("RGB")
	cols, rows = int(project.size[0] / 16), int(project.size[1] / 16)
	for row in range(rows):
		for col in range(cols):
			rCol = project.getpixel((col*16 + 8, row*16 + 8))
			colours.append(Colour("colour{}".format(len(colours)),
			colour=sRGBColor(rCol[0], rCol[1], rCol[2], True),
			nameNull=True))
	return getSwatchFromFileName(file, colours)

def saveSwatch_IMAGE(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .png, .jpg, .webp """
	# Colours should be 16x16 px on a canvas with size 256x(16*ceil(colours/16)
	colours = colourSwatch.colours
	rows = ceil(len(colours)/16)
	image = Image.new("RGB", (256, 16*rows), colours[-1].getRGB255())
	draw = ImageDraw.Draw(image)
	index = 0
	for row in range(rows):
		for col in range(16):
			draw.rectangle([col*16, row*16, (col+1)*16, (row+1)*16],
			fill=colours[index].getRGB255(), width=0)
			index += 1 if index < len(colours) - 1 else 0
	image.save(fileName)


### SVG ###
def openSwatch_SVG(file: str) -> ColourSwatch:
	"""Open a .svg into a colour swatch """
	colours = []
	rCols = set()
	with open(file) as fileData:
		# get a list of colours #rgb, #rrggbb. rgb(r,g,b). rgb(r%,g%,b%)
		rColours = findall(r"(#......)|(#...)|rgb\((.*?,.*?,.*?)\)", fileData.read())
		for rColour in rColours:
			if len(rColour[0]) > 0: # #rrggbb
				col = (int(rColour[0][1:3], 16)/255, int(rColour[0][3:5], 16)/255,
				int(rColour[0][5:7], 16)/255)
			elif len(rColour[1]) > 0: # #rgb
				col = (int(rColour[1][1], 16)/16, int(rColour[1][2], 16)/16,
				int(rColour[1][3], 16)/15)
			else:
				r, g, b = rColour[2].split(",")
				r, g, b = r.strip(), g.strip(), b.strip()
				if r[-1] == "%": # rgb(r%,g%,b%)
					col = (int(r[:-1])/100, int(g[:-1])/100, int(b[:-1])/100)
				else: # rgb(r,g,b)
					col = (int(r)/255, int(g)/255, int(b)/255)
			if col not in rCols:
				rCols.add(col)
				colours.append(Colour("colour{}".format(len(colours)),
				sRGBColor(col[0], col[1], col[2]), True))
	return getSwatchFromFileName(file, colours)

def saveSwatch_SVG(fileName: str, colourSwatch: ColourSwatch):
	""" Save a colour swatch as .svg"""
	colours = colourSwatch.colours
	rows = ceil(len(colours)/16)
	with open(fileName, "w") as fileData:
		colours[-1].toRGB()
		data = [("<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"{0}\" " +
		"width=\"256\" version=\"1.1\">\n\t<rect style=\"fill:#{1}\" " +
		"height=\"{0}\" width=\"256\" x=\"0\" y=\"0\"/>").format(rows*16, "".join(colours[-1].getRGB255Hex()))]
		index = 0
		for row in range(rows):
			for col in range(16):
				colours[index].toRGB()
				data.append("\t<rect style=\"fill:#{}\" height=\"16\" width=\"16\" x=\"{}\" y=\"{}\"/>".format(
				"".join(colours[index].getRGB255Hex()), col*16, row*16))
				if index < len(colours) - 2:
					index += 1
				else:
					break
		data.append("</svg>\n")
		fileData.write("\n".join(data))
