# paint_palette.py (c) 2011 Dany Lebel (Axon_D)
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****


bl_info = {
    "name": "Paint Palettes",
    "author": "Dany Lebel (Axon D)",
    "version": (0, 9, 1),
    "blender": (2, 63, 0),
    "location": "Image Editor and 3D View > Any Paint mode > Color Palette or Weight Palette panel",
    "description": "Palettes for color and weight paint modes",
    "warning": "",
    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
                "Scripts/Paint/Palettes",
    "category": "Paint",
}

"""
This addon brings palettes to the paint modes.

    * Color Palette for Image Painting, Texture Paint and Vertex Paint modes.
    * Weight Palette for the Weight Paint mode.

Set a number of colors (or weights according to the mode) and then associate it
with the brush by using the button under the color.
"""

import bpy
from bpy.props import *


def update_panels():
    pp = bpy.context.scene.palette_props
    current_color = pp.colors[pp.current_color_index].color
    pp.color_name = pp.colors[pp.current_color_index].name
    brush = current_brush()
    brush.color = current_color
    pp.index = pp.current_color_index

def sample():
    pp = bpy.context.scene.palette_props
    current_color = pp.colors[pp.current_color_index]
    brush = current_brush()
    current_color.color = brush.color
    return None

def current_brush():
    context = bpy.context
    if context.area.type == 'VIEW_3D' and context.vertex_paint_object:
        brush = context.tool_settings.vertex_paint.brush
    elif context.area.type == 'VIEW_3D' and context.image_paint_object:
        brush = context.tool_settings.image_paint.brush
    elif context.area.type == 'IMAGE_EDITOR' and  context.space_data.mode == 'PAINT':
        brush = context.tool_settings.image_paint.brush
    else :
        brush = None
    return brush


def update_weight_value():
    pp = bpy.context.scene.palette_props
    tt = bpy.context.tool_settings
    tt.unified_paint_settings.weight = pp.weight_value
    return None


class PALETTE_MT_menu(bpy.types.Menu):
    bl_label = "Presets"
    preset_subdir = ""
    preset_operator = "palette.load_gimp_palette"

    def path_menu(self, searchpaths, operator, props_default={}):
        layout = self.layout
        # hard coded to set the operators 'filepath' to the filename.
        import os
        import bpy.utils

        layout = self.layout
        if not searchpaths[0]:
            layout.label("* Missing Paths *")

        # collect paths
        else :
            files = []
            for directory in searchpaths:
                files.extend([(f, os.path.join(directory, f)) for f in os.listdir(directory)])

            files.sort()

            for f, filepath in files:

                if f.startswith("."):
                    continue

                preset_name = bpy.path.display_name(f)
                props = layout.operator(operator, text=preset_name)

                for attr, value in props_default.items():
                    setattr(props, attr, value)

                props.filepath = filepath
                if operator == "palette.load_gimp_palette":
                    props.menu_idname = self.bl_idname

    def draw_preset(self, context):
        """Define these on the subclass
         - preset_operator
         - preset_subdir
        """
        import bpy
        self.path_menu([bpy.context.scene.palette_props.presets_folder], self.preset_operator)

    draw = draw_preset


class LoadGimpPalette(bpy.types.Operator):
    """Execute a preset"""
    bl_idname = "palette.load_gimp_palette"
    bl_label = "Load a Gimp palette"

    filepath = bpy.props.StringProperty(name="Path",
        description="Path of the Python file to execute",
        maxlen=512, default="")
    menu_idname = bpy.props.StringProperty(name="Menu ID Name",
        description="ID name of the menu this was called from", default="")

    def execute(self, context):
        from os.path import basename
        filepath = self.filepath

        palette_props = bpy.context.scene.palette_props
        palette_props.current_color_index = 0

        # change the menu title to the most recently chosen option
        preset_class = getattr(bpy.types, self.menu_idname)
        preset_class.bl_label = bpy.path.display_name(basename(filepath))


        ts = bpy.context.tool_settings
        palette_props.columns = 0
        if filepath[-4:] == ".gpl":
            gpl = open(filepath, "r")
            lines = gpl.readlines()
            palette_props.notes = ''
            has_color = False
            for index_0, line in enumerate(lines):
                if not line or (line[:12] == "GIMP Palette"):
                    pass
                elif line[:5] == "Name:":
                    palette_props.palette_name = line[5:]
                elif line[:8] == "Columns:":
                    palette_props.columns = int(line[8:])
                elif line[0] == "#":
                    palette_props.notes += line
                else :
                    has_color = True
                    #index_0 = i
                    break
            i = -1
            if has_color:
                for i, ln in enumerate(lines[index_0:]):
                    try:
                        palette_props.colors[i]
                    except IndexError:
                        palette_props.colors.add()
                    color = [float(rgb)/255 for rgb in [ln[0:3], ln[4:7], ln[8:11]]]

                    palette_props.colors[i].color = color

                    palette_props.colors[i].name = ln[12:-1]

            exceeding = i + 1
            while palette_props.colors.__len__() > exceeding:
                palette_props.colors.remove(exceeding)

            if has_color:
                update_panels()
            gpl.close()
            pass
        else :
            self.report({'INFO'}, "Not a supported palette format")

        return {'FINISHED'}


class WriteGimpPalette():
    """Base preset class, only for subclassing
    subclasses must define
     - preset_values
     - preset_subdir """
    bl_options = {'REGISTER'}  # only because invoke_props_popup requires.



    name = bpy.props.StringProperty(name="Name",
        description="Name of the preset, used to make the path name",
        maxlen=64, default="")
    remove_active = bpy.props.BoolProperty(default=False, options={'HIDDEN'})

    @staticmethod
    def as_filename(name):  # could reuse for other presets
        for char in " !@#$%^&*(){}:\";'[]<>,.\\/?":
            name = name.replace(char, '_')
        return name.lower().strip()

    def execute(self, context):
        import os
        pp = bpy.context.scene.palette_props

        if hasattr(self, "pre_cb"):
            self.pre_cb(context)

        preset_menu_class = getattr(bpy.types, self.preset_menu)

        if not self.remove_active:

            if not self.name:
                return {'FINISHED'}

            filename = self.as_filename(self.name)
            target_path = pp.presets_folder

            if not target_path:
                self.report({'WARNING'}, "Failed to create presets path")
                return {'CANCELLED'}

            filepath = os.path.join(target_path, filename) + ".gpl"
            file_preset = open(filepath, 'wb')
            gpl = "GIMP Palette\n"
            gpl += "Name: %s\n" % filename
            gpl += "Columns: %d\n" % pp.columns
            gpl += pp.notes
            if pp.colors.items():
                for i, color in enumerate(pp.colors):
                    gpl += "%3d%4d%4d %s" % (color.color.r * 255, color.color.g * 255, color.color.b * 255, color.name + '\n')
            file_preset.write(bytes(gpl, 'UTF-8'))

            file_preset.close()

            pp.palette_name = filename

        else:
            preset_active = preset_menu_class.bl_label

            # fairly sloppy but convenient.
            filepath = bpy.utils.preset_find(preset_active, self.preset_subdir)

            if not filepath:
                filepath = bpy.utils.preset_find(preset_active,
                    self.preset_subdir, display_name=True)

            if not filepath:
                return {'CANCELLED'}

            if hasattr(self, "remove"):
                self.remove(context, filepath)
            else:
                try:
                    os.remove(filepath)
                except:
                    import traceback
                    traceback.print_exc()

            # XXX, stupid!
            preset_menu_class.bl_label = "Presets"

        if hasattr(self, "post_cb"):
            self.post_cb(context)

        return {'FINISHED'}

    def check(self, context):
        self.name = self.as_filename(self.name)

    def invoke(self, context, event):
        if not self.remove_active:
            wm = context.window_manager
            return wm.invoke_props_dialog(self)
        else:
            return self.execute(context)


class AddPresetPalette(WriteGimpPalette, bpy.types.Operator):
    """Add a Palette Preset"""
    bl_idname = "palette.preset_add"
    bl_label = "Add Palette Preset"
    preset_menu = "PALETTE_MT_menu"

    preset_defines = []
    preset_values = []
    preset_subdir = "palette"


class PALETTE_OT_add_color(bpy.types.Operator):
    bl_label = ""
    bl_description = "Add a Color to the Palette"
    bl_idname = "palette_props.add_color"


    def execute(self, context):
        pp = bpy.context.scene.palette_props
        new_index = 0
        if pp.colors.items():
            new_index = pp.current_color_index + 1
        pp.colors.add()

        last = pp.colors.__len__() - 1


        pp.colors.move(last, new_index)
        pp.current_color_index = new_index
        sample()
        update_panels()
        return {'FINISHED'}


class PALETTE_OT_remove_color(bpy.types.Operator):
    bl_label = ""
    bl_description = "Remove Selected Color"
    bl_idname = "palette_props.remove_color"

    @classmethod
    def poll(cls, context):
        pp = bpy.context.scene.palette_props
        return bool(pp.colors.items())


    def execute(self, context):
        pp = bpy.context.scene.palette_props
        i = pp.current_color_index
        pp.colors.remove(i)

        if pp.current_color_index >= pp.colors.__len__():
            pp.index = pp.current_color_index = pp.colors.__len__() - 1
        return {'FINISHED'}


class PALETTE_OT_sample_tool_color(bpy.types.Operator):
    bl_label = ""
    bl_description = "Sample Tool Color"
    bl_idname = "palette_props.sample_tool_color"

    def execute(self, context):
        pp = bpy.context.scene.palette_props
        brush = current_brush()
        pp.colors[pp.current_color_index].color = brush.color
        return {'FINISHED'}


class IMAGE_OT_select_color(bpy.types.Operator):
    bl_label = ""
    bl_description = "Select this color"
    bl_idname = "paint.select_color"


    color_index = IntProperty()

    def invoke(self, context, event):
        palette_props = bpy.context.scene.palette_props
        palette_props.current_color_index = self.color_index

        update_panels()
        return {'FINISHED'}


def color_palette_draw(self, context):
    palette_props = bpy.context.scene.palette_props


    layout = self.layout


    bpy.types.PALETTE_MT_menu.preset_subdir = palette_props.presets_folder
    row = layout.row(align=True)
    row.menu("PALETTE_MT_menu", text=palette_props.palette_name.rstrip())
    row.operator("palette.preset_add", text="", icon="ZOOMIN")
    row.operator("palette.preset_add", text="", icon="ZOOMOUT").remove_active = True
    col = layout.column(align=True)
    row = col.row(align=True)
    row.operator("palette_props.add_color", icon="ZOOMIN")
    row.prop(palette_props, "index")
    row.operator("palette_props.remove_color", icon="PANEL_CLOSE")
    row = col.row(align=True)
    row.prop(palette_props, "columns")
    if palette_props.colors.items():
        layout = col.box()
        row = layout.row(align=True)
        row.prop(palette_props, "color_name")
        row.operator("palette_props.sample_tool_color", icon="COLOR")

    laycol = layout.column(align=False)

    if palette_props.columns:
        columns = palette_props.columns
    else :
        columns = 16
    for i, color in enumerate(palette_props.colors):
        if not i % columns:
            row1 = laycol.row(align=True)
            row1.scale_y = 0.8
            row2 = laycol.row(align=True)
            row2.scale_y = 0.5

        if i == palette_props.current_color_index:

            row1.prop(palette_props.colors[i], "color", event=True, toggle=True)
            row2.operator("paint.select_color", emboss=False).color_index = i
        else :
            row1.prop(palette_props.colors[i], "color", event=True, toggle=True)
            row2.operator("paint.select_color").color_index = i

    layout = self.layout
    row = layout.row()
    row.prop(palette_props, "presets_folder", text="")

    pass


class BrushButtonsPanel():
    bl_space_type = 'IMAGE_EDITOR'
    bl_region_type = 'UI'

    @classmethod
    def poll(cls, context):
        sima = context.space_data
        toolsettings = context.tool_settings.image_paint
        return sima.show_paint and toolsettings.brush


class PaintPanel():
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = 'Tools'

    @staticmethod
    def paint_settings(context):
        ts = context.tool_settings

        if context.vertex_paint_object:
            return ts.vertex_paint
        elif context.weight_paint_object:
            return ts.weight_paint
        elif context.texture_paint_object:
            return ts.image_paint
        return None


class IMAGE_PT_color_palette(BrushButtonsPanel, bpy.types.Panel):
    bl_label = "Color Palette"
    bl_options = {'DEFAULT_CLOSED'}

    def draw(self, context):
        color_palette_draw(self, context)


class VIEW3D_PT_color_palette(PaintPanel, bpy.types.Panel):
    bl_label = "Color Palette"
    bl_options = {'DEFAULT_CLOSED'}

    @classmethod
    def poll(cls, context):
        return (context.image_paint_object or context.vertex_paint_object)

    def draw(self, context):
        color_palette_draw(self, context)


class VIEW3D_OT_select_weight(bpy.types.Operator):
    bl_label = ""
    bl_description = "Select this weight"
    bl_idname = "paint.select_weight"

    weight_index = IntProperty()

    def current_weight(self):
        pp = bpy.context.scene.palette_props
        if self.weight_index == 0:
            weight = pp.weight_0
        elif self.weight_index == 1:
            weight = pp.weight_1
        elif self.weight_index == 2:
            weight = pp.weight_2
        elif self.weight_index == 3:
            weight = pp.weight_3
        elif self.weight_index == 4:
            weight = pp.weight_4
        elif self.weight_index == 5:
            weight = pp.weight_5
        elif self.weight_index == 6:
            weight = pp.weight_6
        elif self.weight_index == 7:
            weight = pp.weight_7
        elif self.weight_index == 8:
            weight = pp.weight_8
        elif self.weight_index == 9:
            weight = pp.weight_9
        elif self.weight_index == 10:
            weight = pp.weight_10
        return weight

    def invoke(self, context, event):
        palette_props = bpy.context.scene.palette_props

        palette_props.current_weight_index = self.weight_index

        if self.weight_index == 0:
            weight = palette_props.weight_0
        elif self.weight_index == 1:
            weight = palette_props.weight_1
        elif self.weight_index == 2:
            weight = palette_props.weight_2
        elif self.weight_index == 3:
            weight = palette_props.weight_3
        elif self.weight_index == 4:
            weight = palette_props.weight_4
        elif self.weight_index == 5:
            weight = palette_props.weight_5
        elif self.weight_index == 6:
            weight = palette_props.weight_6
        elif self.weight_index == 7:
            weight = palette_props.weight_7
        elif self.weight_index == 8:
            weight = palette_props.weight_8
        elif self.weight_index == 9:
            weight = palette_props.weight_9
        elif self.weight_index == 10:
            weight = palette_props.weight_10
        palette_props.weight = weight
        #bpy.context.tool_settings.vertex_group_weight = weight
        return {'FINISHED'}


class VIEW3D_OT_reset_weight_palette(bpy.types.Operator):
    bl_label = ""
    bl_idname = "paint.reset_weight_palette"


    def execute(self, context):
        palette_props = context.scene.palette_props

        if palette_props.current_weight_index == 0:
            palette_props.weight = 0.0
        palette_props.weight_0 = 0.0

        palette_props.weight_1 = 0.1
        if palette_props.current_weight_index == 1:
            palette_props.weight = 0.1

        if palette_props.current_weight_index == 2:
            palette_props.weight = 0.25
        palette_props.weight_2 = 0.25

        if palette_props.current_weight_index == 3:
            palette_props.weight = 0.3333
        palette_props.weight_3 = 0.3333

        if palette_props.current_weight_index == 4:
            palette_props.weight = 0.4
        palette_props.weight_4 = 0.4

        if palette_props.current_weight_index == 5:
            palette_props.weight = 0.5
        palette_props.weight_5 = 0.5

        if palette_props.current_weight_index == 6:
            palette_props.weight = 0.6
        palette_props.weight_6 = 0.6

        if palette_props.current_weight_index == 7:
            palette_props.weight = 0.6666
        palette_props.weight_7 = 0.6666

        if palette_props.current_weight_index == 8:
            palette_props.weight = 0.75
        palette_props.weight_8 = 0.75

        if palette_props.current_weight_index == 9:
            palette_props.weight = 0.9
        palette_props.weight_9 = 0.9

        if palette_props.current_weight_index == 10:
            palette_props.weight = 1.0
        palette_props.weight_10 = 1.0
        return {'FINISHED'}

class VIEW3D_PT_weight_palette(PaintPanel, bpy.types.Panel):
    bl_label = "Weight Palette"
    bl_options = {'DEFAULT_CLOSED'}

    @classmethod
    def poll(cls, context):
        return context.weight_paint_object

    def draw(self, context):
        palette_props = bpy.context.scene.palette_props
        #vertex_group_weight = bpy.context.tool_settings.unified_paint_settings.weight

        layout = self.layout
        row = layout.row()
        row.prop(palette_props, "weight", slider=True)
        box = layout.box()

        row = box.row()
        if palette_props.current_weight_index == 0:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_0,
                     emboss=False).weight_index = 0
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_0,
                     emboss=True).weight_index = 0

        row = box.row(align=True)
        if palette_props.current_weight_index == 1:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_1,
                     emboss=False).weight_index = 1
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_1,
                     emboss=True).weight_index = 1

        if palette_props.current_weight_index == 2:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_2,
                     emboss=False).weight_index = 2
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_2,
                     emboss=True).weight_index = 2

        if palette_props.current_weight_index == 3:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_3,
                     emboss=False).weight_index = 3
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_3,
                     emboss=True).weight_index = 3

        row = box.row(align=True)
        if palette_props.current_weight_index == 4:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_4,
                     emboss=False).weight_index = 4
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_4,
                     emboss=True).weight_index = 4

        if palette_props.current_weight_index == 5:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_5,
                     emboss=False).weight_index = 5
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_5,
                     emboss=True).weight_index = 5

        if palette_props.current_weight_index == 6:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_6,
                     emboss=False).weight_index = 6
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_6,
                     emboss=True).weight_index = 6

        row = box.row(align=True)
        if palette_props.current_weight_index == 7:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_7,
                     emboss=False).weight_index = 7
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_7,
                     emboss=True).weight_index = 7

        if palette_props.current_weight_index == 8:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_8,
                     emboss=False).weight_index = 8
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_8,
                     emboss=True).weight_index = 8

        if palette_props.current_weight_index == 9:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_9,
                     emboss=False).weight_index = 9
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_9,
                     emboss=True).weight_index = 9

        row = box.row(align=True)
        if palette_props.current_weight_index == 10:
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_10,
                     emboss=False).weight_index = 10
        else :
            row.operator("paint.select_weight", text="%.2f" % palette_props.weight_10,
                     emboss=True).weight_index = 10

        row = layout.row()
        row.operator("paint.reset_weight_palette", text="Reset")


class Colors(bpy.types.PropertyGroup):
    """Class for colors CollectionProperty"""
    color = bpy.props.FloatVectorProperty(
        name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1,
        step=1, precision=3, subtype='COLOR_GAMMA', size=3)


class Weights(bpy.types.PropertyGroup):
    """Class for Weights Collection Property"""

    weight = bpy.props.FloatProperty(
        default=0.0, min=0.0, max=1.0, precision=3)


class PaletteProps(bpy.types.PropertyGroup):

    def update_color_name(self, context):
        pp = bpy.context.scene.palette_props
        pp.colors[pp.current_color_index].name = pp.color_name
        return None

    def move_color(self, context):
        pp = bpy.context.scene.palette_props
        if pp.colors.items() and pp.current_color_index != pp.index:
            if pp.index >= pp.colors.__len__():
                pp.index = pp.colors.__len__() - 1
            pp.colors.move(pp.current_color_index, pp.index)
            pp.current_color_index = pp.index
        return None

    def update_weight(self, context):
        pp = context.scene.palette_props
        weight = pp.weight
        if pp.current_weight_index == 0:
            pp.weight_0 = weight
        elif pp.current_weight_index == 1:
            pp.weight_1 = weight
        elif pp.current_weight_index == 2:
            pp.weight_2 = weight
        elif pp.current_weight_index == 3:
            pp.weight_3 = weight
        elif pp.current_weight_index == 4:
            pp.weight_4 = weight
        elif pp.current_weight_index == 5:
            pp.weight_5 = weight
        elif pp.current_weight_index == 6:
            pp.weight_6 = weight
        elif pp.current_weight_index == 7:
            pp.weight_7 = weight
        elif pp.current_weight_index == 8:
            pp.weight_8 = weight
        elif pp.current_weight_index == 9:
            pp.weight_9 = weight
        elif pp.current_weight_index == 10:
            pp.weight_10 = weight
        bpy.context.tool_settings.unified_paint_settings.weight = weight
        #bpy.context.tool_settings.vertex_group_weight = weight
        return None

    palette_name = StringProperty(
        name="Palette Name", default="Preset", subtype='FILE_NAME')

    color_name = StringProperty(
        name="", description="Color Name", default="Untitled", update=update_color_name)

    columns = IntProperty(
        name="Columns",
        description="Number of Columns",
        min=0, max=16, default=0)

    index = IntProperty(
        name="Index",
        description="Move Selected Color",
        min=0,
        update=move_color)

    notes = StringProperty(
        name="Palette Notes", default="#\n")

    current_color_index = IntProperty(
        name="Current Color Index", description="", default=0, min=0)

    current_weight_index = IntProperty(
        name="Current Color Index", description="", default=10, min=-1)

    presets_folder = StringProperty(name="",
        description="Palettes Folder",
        subtype="DIR_PATH")

    colors = bpy.props.CollectionProperty(type=Colors)

    weight = bpy.props.FloatProperty(name="Weight",
        default=0.0, min=0.0, max=1.0, precision=3, update=update_weight)

    weight_0 = bpy.props.FloatProperty(
        default=0.0, min=0.0, max=1.0, precision=3)
    weight_1 = bpy.props.FloatProperty(
        default=0.1, min=0.0, max=1.0, precision=3)
    weight_2 = bpy.props.FloatProperty(
        default=0.25, min=0.0, max=1.0, precision=3)
    weight_3 = bpy.props.FloatProperty(
        default=0.333, min=0.0, max=1.0, precision=3)
    weight_4 = bpy.props.FloatProperty(
        default=0.4, min=0.0, max=1.0, precision=3)
    weight_5 = bpy.props.FloatProperty(
        default=0.5, min=0.0, max=1.0, precision=3)
    weight_6 = bpy.props.FloatProperty(
        default=0.6, min=0.0, max=1.0, precision=3)
    weight_7 = bpy.props.FloatProperty(
        default=0.6666, min=0.0, max=1.0, precision=3)
    weight_8 = bpy.props.FloatProperty(
        default=0.75, min=0.0, max=1.0, precision=3)
    weight_9 = bpy.props.FloatProperty(
        default=0.9, min=0.0, max=1.0, precision=3)
    weight_10 = bpy.props.FloatProperty(
        default=1.0, min=0.0, max=1.0, precision=3)
    pass

def register():
    bpy.utils.register_module(__name__)

    bpy.types.Scene.palette_props = PointerProperty(
            type=PaletteProps, name="Palette Props", description="")
    pass


def unregister():
    bpy.utils.unregister_module(__name__)

    del bpy.types.Scene.palette_props
    pass


if __name__ == "__main__":
    register()


# To Do List
# ToDo1 Overiting the current file
# ToDo3 Foreground Background


