bl_info = {
    "name": "Mesh Layers",
    "author": "Gregory Smirnoff",
    "version": (0, 0, 1),
    "blender": (2, 80, 0),
    "location": "Object Panel > Mesh Layers",
    "description": "",
    "warning": "",
    "wiki_url": "",
    "category": "Mesh",
}


import bpy
from bpy.types import Operator, AddonPreferences, PropertyGroup, UIList, Menu, Panel
from bpy.props import StringProperty, IntProperty, FloatProperty, FloatVectorProperty, BoolProperty, CollectionProperty


### Preferences

#Base Functions

 
        
### UI


class MESHLAY_PT_MAIN(Panel):
    bl_label = "Mesh Layers"
    bl_order = 21
    bl_idname = "MESHLAY_PT_MAINPANEL"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "data"
    bl_options = {'DEFAULT_CLOSED'}

    @classmethod
    def poll(cls, context):
        return context.object.type == 'MESH' and context.object.mode == 'OBJECT'   

    def draw(self, context):
        
        layout = self.layout
        
        ob = context.object
        
        main = layout.row()
        
        ul_list = main.column()
        ul_list_opers = main.column()
     
        ul_list.template_list("MESH_LAYERS_UL_LIST", "", ob, "ml_list", ob, "ml_list_index", rows=6)
        
      
        
        ul_list_opers.operator('ml.add', text='', icon = 'ADD')      
        ul_list_opers.operator('ml.remove',text='', icon = 'REMOVE')
        
        ul_list_opers.separator()
             
        #ul_list_opers.operator("ml.move", text='', icon="TRIA_UP").direction = 'UP'
        #ul_list_opers.operator("ml.move",text='', icon="TRIA_DOWN").direction = 'DOWN'  
        
        ul_list_opers.separator() 
        
           


class MESHLAY_OP_ADD(Operator):
    bl_label = "Add Layer"
    bl_description = 'Add Layer'
    bl_idname = 'ml.add'
    
    def execute(self, context): 
         
        ob = context.object
        item = ob.ml_list.add()
        ob.ml_list_index = (len(ob.ml_list)-1)

        item.name = ob.data.name
        item.base_mesh = ob.data
        item.mesh = ob.data.copy()
        context.object.data = item.mesh
        
        return {"FINISHED"}
    

    
class MESHLAY_OP_MOVE(Operator):
    
    bl_idname = "ml.move"
    bl_label = ""
    bl_description = "Move selected set up or down"

    direction:bpy.props.EnumProperty(items=( \
        ('UP', "Up", "Move up"), \
        ('DOWN', "Down", "Move down"))
    )
    

    def execute(self, context):
        length = len(context.window_manager.rss_list)
        if length > 1:
            c = context.window_manager
            d = -1 if self.direction == 'UP' else 1
            new_index = (c.rss_list_index + d) % len(c.rss_list)
            c.rss_list.move(c.rss_list_index, new_index)
            c.rss_list_index = new_index
            
        return {'FINISHED'}     


class MESHLAY_OP_REMOVE(Operator):
    bl_label = "Remove Layer"
    bl_description = 'Remome Layer'
    bl_idname = 'ml.remove'
    
    def execute(self, context):
        
        ob = context.object

        ls = ob.ml_list
        index = ob.ml_list_index      

        #if count == 1:
            #context.object.data = item.mesh 

        ob.ml_list.remove(ob.ml_list_index)
        if ob.ml_list_index == 0:
            ob.ml_list_index -= 1
            
        if ob.ml_list_index > (len(ls)-1):
            ob.ml_list_index = (len(ls)-1)  

        count = len(ls)

        if count:
            index = ob.ml_list_index   
            print("Index is: ", index)   
            item = ob.ml_list[index]            
            context.object.data = item.mesh                                
        

        return {"FINISHED"}

  
    
    
    

####_UI_List________________________###############################

class MeshLayerItem(PropertyGroup):

    def name_update_func(self, context):
        context.object.data.name = self.name   

    name : StringProperty(update=name_update_func)
    base_mesh : bpy.props.PointerProperty(type=bpy.types.Mesh)
    mesh : bpy.props.PointerProperty(type=bpy.types.Mesh)
    
    
#______________________________________________________________________________________________________________________________

class MESH_LAYERS_UL_LIST(UIList):
    
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):

        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            
                #layout.prop(item, "name", text="", emboss=False, icon='MESH_DATA') #, icon="DOT"

                if index!=context.object.ml_list_index:
                    layout.prop(item, "name", text="", emboss=False, icon='MESH_DATA') #, icon="DOT"
                
                if index==context.object.ml_list_index:
                    layout.prop(item, "name", text="", emboss=False, icon='EDITMODE_HLT') #, icon="ANIM"
                    
        elif self.layout_type in {'GRID'}:
            pass 
                       

#______________________________________________________________________________________________________________________________    

classes = [
    MESHLAY_PT_MAIN,
    MESHLAY_OP_ADD,
    MESHLAY_OP_MOVE,
    MESHLAY_OP_REMOVE,  
    MeshLayerItem,
    MESH_LAYERS_UL_LIST, 
]  


def layer_update_func(self, context):
    ob = context.object
    ob.data = ob.ml_list[ob.ml_list_index].mesh
     
        
def register():
    
    for cls in classes:
        bpy.utils.register_class(cls)
    
    bpy.types.Object.ml_list = CollectionProperty(type=MeshLayerItem)
    bpy.types.Object.ml_list_index = IntProperty(min=0, update=layer_update_func)
     

def unregister():
    
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)

    del bpy.types.Object.ml_list
    del bpy.types.Object.ml_list_index



if __name__ == "__main__":
    register()        