class FLUENT_OT_Wire(bpy.types.Operator):
    bl_idname = "wm.wire"
    bl_label="Place wire"
    bl_options={'REGISTER','UNDO'}

    def add_wire_style(self, type):
        if type == 'CIRCULAR_CIRCLE':
            file_path_wire = os.path.dirname(__file__) + "\\wire_01.blend\\Object\\"
            self.fluent_curve['curve_obj'].select_set(False)
            bpy.ops.wm.append(filename='CIRCULAR_CIRCLE_mesh', directory=file_path_wire)
            self.fluent_curve['curve_obj'].data.bevel_depth = 0
            wire_mesh = bpy.context.selected_objects[0]
            wire_mesh.select_set(False)
            wire_mesh.modifiers['Curve'].object = self.fluent_curve['curve_obj']
            wire_mesh.modifiers['Curve_Array'].curve = self.fluent_curve['curve_obj']
            self.fluent_curve['wire_obj'] = wire_mesh
        elif type == 'ARRAY_CIRCLE':
            file_path_wire = os.path.dirname(__file__) + "\\wire_02.blend\\Object\\"
            self.fluent_curve['curve_obj'].select_set(False)
            bpy.ops.wm.append(filename='ARRAY_CIRCLE_mesh', directory=file_path_wire)
            self.fluent_curve['curve_obj'].data.bevel_depth = 0
            wire_mesh = bpy.context.selected_objects[0]
            wire_mesh.select_set(False)
            wire_mesh.modifiers['Curve'].object = self.fluent_curve['curve_obj']
            wire_mesh.modifiers['Curve_Array'].curve = self.fluent_curve['curve_obj']
            self.fluent_curve['wire_obj'] = wire_mesh

    def fly_adjustement(self, event, obj, action):
        modifier_name = action.split('#')[1]

        if modifier_name == 'Cable_Radius':
            if not self.build_step:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].strength
                self.build_step = 'adjust'
            if self.shift_work:
                increment = 3000
            elif self.ctrl_work:
                increment = 30
            else:
                increment = 300
            if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].strength

            self.fluent_curve['wire_obj'].modifiers[modifier_name].strength = self.previous_value - ((self.mouse_x - self.x_mouse_slider_origin)/increment)

            if self.wire_style == 'ARRAY_CIRCLE':
                d = self.fluent_curve['wire_obj'].modifiers['Cable_Radius'].strength
                n = self.fluent_curve['wire_obj'].modifiers['ArrayX'].count
                offset = self.fluent_curve['wire_obj'].modifiers['ArrayX'].relative_offset_displace[0] * -1
                self.fluent_curve['wire_obj'].modifiers['Displace_To_Center'].strength = 2*d*(n-1)*offset
        #############################################################
        if modifier_name == 'Circular_Displace':
            if not self.build_step:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].strength
                self.build_step = 'adjust'
            if self.shift_work:
                increment = 3000
            elif self.ctrl_work:
                increment = 30
            else:
                increment = 300
            if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].strength

            self.fluent_curve['wire_obj'].modifiers[modifier_name].strength = self.previous_value - ((self.mouse_x - self.x_mouse_slider_origin)/increment)
        #############################################################
        if modifier_name == 'Screw.001':
            if not self.build_step:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].screw_offset
                self.build_step = 'adjust'
            if self.shift_work:
                increment = 3000
            elif self.ctrl_work:
                increment = 30
            else:
                increment = 300
            if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].screw_offset

            self.fluent_curve['wire_obj'].modifiers[modifier_name].screw_offset = self.previous_value - ((self.mouse_x - self.x_mouse_slider_origin)/increment)
        #############################################################
        if modifier_name == 'Circular_Array':
            if not self.build_step:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].count
                self.build_step = 'adjust'
            if self.shift_work:
                increment = 1000
            elif self.ctrl_work:
                increment = 10
            else:
                increment = 100
            if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].count

            self.fluent_curve['wire_obj'].modifiers[modifier_name].count = self.previous_value - ((self.mouse_x - self.x_mouse_slider_origin)/increment)
            empty = self.fluent_curve['wire_obj'].children[0]
            print(empty.rotation_euler[2])
            empty.rotation_euler[2] = math.radians(360/self.fluent_curve['wire_obj'].modifiers[modifier_name].count)

        #############################################################
        if modifier_name == 'ArrayX':
            if not self.build_step:
                self.x_mouse_slider_origin = self.mouse_x
                self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].count
                self.build_step = 'adjust'
                self.other_adjustement = 'count'
            if self.shift_work:
                increment = 3000
            elif self.ctrl_work:
                increment = 30
            else:
                increment = 300
            if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                self.x_mouse_slider_origin = self.mouse_x
                if self.other_adjustement == 'count':
                    self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].count
                else:
                    self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].relative_offset_displace[0]

            if event.value == 'PRESS' and event.type == 'S':
                if self.other_adjustement == 'count':
                    self.other_adjustement = 'offset'
                    self.x_mouse_slider_origin = self.mouse_x
                    self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].relative_offset_displace[0]
                else:
                    self.other_adjustement = 'count'
                    self.x_mouse_slider_origin = self.mouse_x
                    self.previous_value = self.fluent_curve['wire_obj'].modifiers[modifier_name].count

            if self.other_adjustement == 'count':
                self.fluent_curve['wire_obj'].modifiers[modifier_name].count = int(self.previous_value + ((self.mouse_x - self.x_mouse_slider_origin)/(increment/4)))
            elif self.other_adjustement == 'offset':
                self.fluent_curve['wire_obj'].modifiers[modifier_name].relative_offset_displace[0] = self.previous_value - ((self.mouse_x - self.x_mouse_slider_origin)/increment)

            d = self.fluent_curve['wire_obj'].modifiers['Cable_Radius'].strength
            n = self.fluent_curve['wire_obj'].modifiers['ArrayX'].count
            offset = self.fluent_curve['wire_obj'].modifiers['ArrayX'].relative_offset_displace[0] * -1
            self.fluent_curve['wire_obj'].modifiers['Displace_To_Center'].strength = 2*d*(n-1)*offset

        if event.value == 'PRESS' and event.type == 'LEFTMOUSE':
            self.action = self.build_step = None

    def modal(self, context, event):
        self.mouse_x = event.mouse_region_x
        self.mouse_y = event.mouse_region_y
        if event.value == 'PRESS' and event.type == 'LEFTMOUSE':
            self.mouse_click = True
        if event.value == 'RELEASE' and event.type == 'LEFTMOUSE':
            self.mouse_click = False
        # gestion des evenements du shift
        if event.shift and not self.shift_press and not self.shift_work:
            self.shift_press = True
        elif event.shift and self.shift_press:
            self.shift_press = False
            self.shift_work = True
        elif not event.shift and self.shift_work:
            self.shift_release = True
            self.shift_work = False
        elif not event.shift and self.shift_release:
            self.shift_release = False
        else:
            self.shift_press = False
        # gestion des evenements du ctrl
        if event.ctrl and not self.ctrl_press and not self.ctrl_work:
            self.ctrl_press = True
        elif event.ctrl and self.ctrl_press:
            self.ctrl_press = False
            self.ctrl_work = True
        elif not event.ctrl and self.ctrl_work:
            self.ctrl_release = True
            self.ctrl_work = False
        elif not event.ctrl and self.ctrl_release:
            self.ctrl_release = False
        else:
            self.ctrl_press = False

        if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
            return {'PASS_THROUGH'}

        draw_callback_px(self, context)

        if event.value == 'PRESS' and event.type == 'LEFTMOUSE':
            self.mouse_click = True
        if event.value == 'RELEASE' and event.type == 'LEFTMOUSE':
            self.mouse_click = False

        if not self.fluent_curve['added'] and self.fluent_curve['first_point'] and self.fluent_curve['second_point']:
            print('add curve')
            bpy.ops.curve.primitive_bezier_curve_add()
            self.fluent_curve['curve_obj'] = active_object('GET')

            spline = active_object('GET').data.splines[0]

            a = spline.bezier_points[0]
            b = spline.bezier_points[1]

            a.co = self.fluent_curve['first_point']['hit']
            b.co = self.fluent_curve['second_point']['hit']

            a.handle_left = a.co - (self.fluent_curve['stiffness'] * self.fluent_curve['first_point']['normal'])
            a.handle_right = a.co + (self.fluent_curve['stiffness'] * self.fluent_curve['first_point']['normal'])

            b.handle_left = b.co + (self.fluent_curve['stiffness'] * self.fluent_curve['second_point']['normal'])
            b.handle_right = b.co - (self.fluent_curve['stiffness'] * self.fluent_curve['second_point']['normal'])

            self.fluent_curve['curve_obj'].data.bevel_depth = 0.15
            self.fluent_curve['curve_obj'].data.resolution_u = 64
            self.fluent_curve['curve_obj'].data.twist_mode = 'Z_UP'
            self.fluent_curve['curve_obj'].data.twist_smooth = 8

            self.fluent_curve['added'] = True

        if event.value == 'PRESS' and event.type == 'LEFTMOUSE' and not self.fluent_curve['second_point'] and self.fluent_curve['first_point']:
            self.fluent_curve['second_point'] = click_on(context, self.mouse_x, self.mouse_y)

        if event.value == 'PRESS' and event.type == 'LEFTMOUSE' and not self.fluent_curve['first_point']:
            self.fluent_curve['first_point'] = click_on(context, self.mouse_x, self.mouse_y)
            print('self.fluent_curve[first_point] : ', self.fluent_curve['first_point'])

        try:
            if event.mouse_region_x != self.x_mouse_slider_origin and self.action == 'RADIUS':
                if self.shift_work:
                    increment = 3000
                elif self.ctrl_work:
                    increment = 30
                else:
                    increment = 300
                if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                    self.x_mouse_slider_origin = event.mouse_region_x
                    self.previous_value = self.fluent_curve['curve_obj'].data.bevel_depth

                self.fluent_curve['curve_obj'].data.bevel_depth = self.previous_value - ((event.mouse_region_x - self.x_mouse_slider_origin)/increment)

            if event.mouse_region_x != self.x_mouse_slider_origin and self.action == 'STIFFNESS':
                if self.shift_work:
                    increment = 3000
                elif self.ctrl_work:
                    increment = 30
                else:
                    increment = 300
                if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                    self.x_mouse_slider_origin = event.mouse_region_x
                    self.previous_value = self.fluent_curve['stiffness']

                self.fluent_curve['stiffness'] = self.previous_value - ((event.mouse_region_x - self.x_mouse_slider_origin)/increment)

                spline = self.fluent_curve['curve_obj'].data.splines[0]

                a = spline.bezier_points[0]
                b = spline.bezier_points[1]

                first_vec = Vector((self.fluent_curve['first_point']['normal'][0], self.fluent_curve['first_point']['normal'][1], self.fluent_curve['first_point']['normal'][2]))
                second_vec = Vector((self.fluent_curve['second_point']['normal'][0], self.fluent_curve['second_point']['normal'][1], self.fluent_curve['second_point']['normal'][2]))

                print(first_vec)

                a.handle_left = a.co - (self.fluent_curve['stiffness'] * first_vec)
                a.handle_right = a.co + (self.fluent_curve['stiffness'] * first_vec)

                b.handle_left = b.co + (self.fluent_curve['stiffness'] * second_vec)
                b.handle_right = b.co - (self.fluent_curve['stiffness'] * second_vec)

            if event.mouse_region_x != self.x_mouse_slider_origin and self.action == 'CURVE_RESOLUTION':
                if self.shift_work:
                    increment = 300
                elif self.ctrl_work:
                    increment = 3
                else:
                    increment = 30
                if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                    self.x_mouse_slider_origin = event.mouse_region_x
                    self.previous_value = self.fluent_curve['curve_obj'].data.resolution_u

                self.fluent_curve['curve_obj'].data.resolution_u = self.previous_value + ((event.mouse_region_x - self.x_mouse_slider_origin)/increment)

            if event.mouse_region_x != self.x_mouse_slider_origin and self.action == 'BEVEL_RESOLUTION':
                if self.shift_work:
                    increment = 300
                elif self.ctrl_work:
                    increment = 3
                else:
                    increment = 30
                if self.shift_press or self.shift_release or self.ctrl_press or self.ctrl_release:
                    self.x_mouse_slider_origin = event.mouse_region_x
                    self.previous_value = self.fluent_curve['curve_obj'].data.bevel_resolution

                self.fluent_curve['curve_obj'].data.bevel_resolution = self.previous_value + ((event.mouse_region_x - self.x_mouse_slider_origin)/increment)

            if event.value == 'PRESS' and event.type == 'LEFTMOUSE' and self.action:
                self.action = None

        except:pass
        if event.value == 'PRESS' and event.type == 'W':
            if self.fluent_curve['curve_obj'].show_wire:
                self.fluent_curve['curve_obj'].show_wire = False
                try:
                    self.fluent_curve['wire_obj'].show_wire = False
                except:pass
            else:
                self.fluent_curve['curve_obj'].show_wire = True
                try:
                    self.fluent_curve['wire_obj'].show_wire = True
                except:pass

        try:
            self.display_menu.hover(event.mouse_region_x, event.mouse_region_y)
            self.menu_hover = self.display_menu.get_menu_hover()
            if not self.mouse_click and self.display_menu:
                self.action = self.display_menu.action()
                self.display_menu = None
                self.x_mouse_slider_origin = event.mouse_region_x
                if self.action == 'RADIUS':
                    self.previous_value = self.fluent_curve['curve_obj'].data.bevel_depth
                elif self.action == 'STIFFNESS':
                    self.previous_value = self.fluent_curve['stiffness']
                elif self.action == 'CURVE_RESOLUTION':
                    self.previous_value = self.fluent_curve['curve_obj'].data.resolution_u
                elif self.action == 'BEVEL_RESOLUTION':
                    self.previous_value = self.fluent_curve['curve_obj'].data.bevel_resolution
                elif self.action == 'CIRCULAR_CIRCLE':
                    self.wire_style = 'CIRCULAR_CIRCLE'
                    self.fluent_curve['wire_style'] = 'CIRCULAR_CIRCLE'
                    self.add_wire_style('CIRCULAR_CIRCLE')
                elif self.action == 'ARRAY_CIRCLE':
                    self.wire_style = 'ARRAY_CIRCLE'
                    self.fluent_curve['wire_style'] = 'ARRAY_CIRCLE'
                    self.add_wire_style('ARRAY_CIRCLE')
                elif 'ADJUSTMENT' in self.action:
                    self.fly_adjustement(event, self.fluent_curve['wire_obj'], self.action)
        except Exception as e:
            print(e)

        try:
            if self.build_step == 'adjust':
                self.fly_adjustement(event, self.fluent_curve['wire_obj'], self.action)
        except:
            self.build_step = None

        if self.fluent_curve['added'] and self.mouse_click and not self.action:
            if self.display_menu == None:
                if self.wire_style == 'CIRCULAR_CIRCLE':
                    self.circular_circle.set_position(event.mouse_region_x, event.mouse_region_y)
                    self.display_menu = self.circular_circle
                elif self.wire_style == 'ARRAY_CIRCLE':
                    self.array_circle.set_position(event.mouse_region_x, event.mouse_region_y)
                    self.display_menu = self.array_circle
                else:
                    self.wire_menu.set_position(event.mouse_region_x, event.mouse_region_y)
                    self.display_menu = self.wire_menu
        else:
            self.display_menu = None

        if event.type == 'ESC':
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            return {'CANCELLED'}
        if event.value == 'PRESS' and event.type == 'RIGHTMOUSE':
            self.fluent_curve['curve_obj']['fluent_curve'] = self.fluent_curve
            self.fluent_curve['curve_obj']['fluent_type'] = 'wire'
            if self.fluent_curve['wire_obj']:
                self.fluent_curve['wire_obj']['fluent_curve'] = self.fluent_curve
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            return {'FINISHED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        self.face_one = {'normal':None, 'location':None}
        self.face_two = {'normal':None, 'location':None}
        self.fluent_curve = {'added':False, 'curve_obj':None, 'stiffness':4, 'wire_obj':None, 'first_point':None, 'second_point':None, 'wire_style':None}

        self.build_step = None

        self.wire_style = None

        self.screen_text = 'Curve tool'

        self.display_menu = None
        self.action = None
        self.previous_value = None
        self.x_mouse_slider_origin = None
        self.other_adjustement = None

        self.shift_press = False
        self.shift_release = False
        self.shift_work = False
        self.ctrl_press = False
        self.ctrl_release = False
        self.ctrl_work = False
        self.mouse_x = event.mouse_region_x
        self.mouse_y = event.mouse_region_y
        self.mouse_click = False

        self.wire_menu = F_Menu(event.mouse_region_x, event.mouse_region_y)
        self.wire_menu.set_position(event.mouse_region_x, event.mouse_region_y)
        self.wire_menu.add_block('modifiers')
        self.wire_menu.add_item('modifiers', 'RADIUS', 'Radius', 'BUTTON')
        self.wire_menu.add_item('modifiers', 'BEVEL_RESOLUTION', 'Bevel resolution', 'BUTTON')
        self.wire_menu.add_item('modifiers', 'CURVE_RESOLUTION', 'Curve resolution', 'BUTTON')
        self.wire_menu.add_item('modifiers', 'STIFFNESS', 'Root strength', 'BUTTON')
        self.wire_menu.add_item('modifiers', 'CIRCULAR_CIRCLE', 'Multi-wire : Circular', 'BUTTON')
        self.wire_menu.add_item('modifiers', 'ARRAY_CIRCLE', 'Multi-wire : Flat', 'BUTTON')

        self.circular_circle = F_Menu(event.mouse_region_x, event.mouse_region_y)
        self.circular_circle.set_position(event.mouse_region_x, event.mouse_region_y)
        self.circular_circle.add_block('modifiers')
        self.circular_circle.add_item('modifiers', 'CURVE_RESOLUTION', 'Curve resolution', 'BUTTON')
        self.circular_circle.add_item('modifiers', 'STIFFNESS', 'Root strength', 'BUTTON')
        self.circular_circle.add_item('modifiers', 'ADJUSTMENT#Cable_Radius', 'Cable radius', 'BUTTON')
        self.circular_circle.add_item('modifiers', 'ADJUSTMENT#Circular_Displace', 'Array radius', 'BUTTON')
        self.circular_circle.add_item('modifiers', 'ADJUSTMENT#Screw.001', 'Twist', 'BUTTON')
        self.circular_circle.add_item('modifiers', 'ADJUSTMENT#Circular_Array', 'Number of wire', 'BUTTON')

        self.array_circle = F_Menu(event.mouse_region_x, event.mouse_region_y)
        self.array_circle.set_position(event.mouse_region_x, event.mouse_region_y)
        self.array_circle.add_block('modifiers')
        self.array_circle.add_item('modifiers', 'CURVE_RESOLUTION', 'Curve resolution', 'BUTTON')
        self.array_circle.add_item('modifiers', 'STIFFNESS', 'Root strength', 'BUTTON')
        self.array_circle.add_item('modifiers', 'ADJUSTMENT#Cable_Radius', 'Cable radius', 'BUTTON')
        self.array_circle.add_item('modifiers', 'ADJUSTMENT#ArrayX', 'Count/Offset', 'BUTTON')

        try:
            obj = active_object('GET')
            if obj.get('fluent_type') and obj['fluent_type'] == 'wire':
                self.fluent_curve = obj['fluent_curve']
                self.wire_style = self.fluent_curve['wire_style']
        except:pass


        args = (self, context)
        self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
        context.window_manager.modal_handler_add(self)
        bpy.ops.view3d.snap_cursor_to_center()
        return {'RUNNING_MODAL'}
