extends MarginContainer

export( bool ) var is_movable = true
export( bool ) var is_resizable = true
export( bool ) var is_borderless = false
export( bool ) var has_footer = true

export( String ) var title = "Window"

export( Color ) var content_color = Color( 1.0, 1.0, 1.0, 1.0 )# test
export( Color ) var background_color = Color( 1.0, 1.0, 1.0, 1.0 )
export( Texture ) var background_texture = null

export( Vector2 ) var min_size= Vector2( 128, 128 )
export( Rect2 ) var content_margin = Rect2( 8, 8, 8, 8 )

signal window_clicked( window )

onready var header_box = $parts/header_box
onready var content_box = $parts/content_box
onready var footer_box = $parts/footer_box

var current_rect_size = Vector2( 0, 0 )
var current_rect_position = Vector2( -1, -1 )
var is_resizing = false
var is_moving = false
var size_changed = true

func add_child_to_content( node):
    if self.get_content():
        self.get_content().add_child(node)
#    else:
#        .add_child( node )
#    prints(self.get_name()+" just fathered", node.get_name())
    
func add_window_part( node ):
    add_child( node )
    
func set_mouse_pass_to_children( node ):
    for child in node.get_children():
        set_mouse_pass_to_children( child )
    if node is Control:
        node.mouse_filter = MOUSE_FILTER_PASS
        
#func _ready():
func _enter_tree():
    ########
    #### Window's part création.
    # The interal elements structure is:
    # self - MarginContainer
    #     background - NinePatchRect
    #     parts - VBoxContainer 
    #        header_box - MarginContainer
    #            header - HBoxContainer
    #                quit - TextureButton
    #                close - TextureButton
    #                open - TextureButton
    #                label - Label
    #        content_box - MarginContainer
    #            scroll_container - Scrollcontainer
    #                content - VBoxContainer
    #        footer_box - MarginContainer
    #            footer - HBoxContainer
    #                contextual_help - Label
    #                resize - TextureButton

    ###
    # self
    self.size_flags_horizontal = SIZE_EXPAND
    self.size_flags_vertical = SIZE_EXPAND
    
    self.set( "custom_constants/margin_right", 0)
    self.set( "custom_constants/margin_top", 0)
    self.set( "custom_constants/margin_left", 0)
    self.set( "custom_constants/margin_bottom", 0)
    
    
    self.connect ( "gui_input", self, "_on_window_gui_input" )
    ###
    ###
    # background
    var background
    if not self.has_node( "background" ):
        background = NinePatchRect.new()
        background.name = "background"
        if not background_texture:
            var background_image = Image.new()
            if not background_image.load( "res://addons/ui_window/background_default.jpg" ) == OK :
                print("Erreur lors du chargement de l'image: "+str("res://addons/ui_window/background_default.jpg") )
            background.texture = ImageTexture.new()
            background.texture.create_from_image( background_image )
        else:
            background.texture = background_texture
            
        background.texture.flags = Texture.FLAG_FILTER | Texture.FLAG_REPEAT
        background.axis_stretch_horizontal = NinePatchRect.AXIS_STRETCH_MODE_TILE
        background.axis_stretch_vertical = NinePatchRect.AXIS_STRETCH_MODE_TILE
        
        background.size_flags_horizontal = SIZE_EXPAND_FILL
        background.size_flags_vertical = SIZE_EXPAND_FILL
        
        background.region_rect = Rect2( 0, 0, 0, 0 )
        background.patch_margin_left = 4
        background.patch_margin_top = 32
        background.patch_margin_right = 4
        background.patch_margin_bottom = 4
        
        background.self_modulate = background_color
        
        self.add_window_part( background )
#        background.set_owner( self ) 
    ###
    ###
    # parts
    var parts
    if not self.has_node( "parts" ):
        parts = VBoxContainer.new()
        parts.name = "parts"
        parts.size_flags_horizontal = SIZE_EXPAND_FILL
        parts.size_flags_vertical = SIZE_EXPAND_FILL
        self.add_window_part( parts )
#        parts.set_owner( self ) 
    ###
    ###
    # header_box
    var header_box
    if not parts.has_node( "header_box" ):
        header_box = MarginContainer.new()
        header_box.name = "header_box"
        header_box.size_flags_horizontal = SIZE_EXPAND_FILL
        header_box.size_flags_vertical = SIZE_SHRINK_CENTER
    
        header_box.set( "custom_constants/margin_right", 4)
        header_box.set( "custom_constants/margin_top", 4)
        header_box.set( "custom_constants/margin_left", 4)
        header_box.set( "custom_constants/margin_bottom", 4)
    
        if is_movable:
            header_box.mouse_default_cursor_shape = CURSOR_MOVE
        parts.add_child( header_box )
#        header_box.set_owner( parts ) 
        header_box.connect ( "gui_input", self, "_on_Header_gui_input" )
    ###    
    ###
    # header
    var header
    if not header_box.has_node( "header" ):
        header = HBoxContainer.new()
        header.name = "header"
        header.size_flags_horizontal = SIZE_EXPAND_FILL
        header.size_flags_vertical = SIZE_EXPAND | SIZE_SHRINK_CENTER
        if is_movable:
            header.mouse_default_cursor_shape = CURSOR_MOVE
        header_box.add_child( header )
#        header.set_owner( header_box ) 
    ###
    ###
    # quit
    var quit_button
    if not header.has_node( "quit" ):
        quit_button = TextureButton.new()
        quit_button.name = "quit"
        quit_button.size_flags_horizontal = SIZE_SHRINK_END
        quit_button.size_flags_vertical = SIZE_SHRINK_CENTER
        
        var tex_quit = ImageTexture.new()
        var img_quit = Image.new()
        img_quit.load( "res://assets/GUI/images/button_quit.png" )
        tex_quit.create_from_image( img_quit )
        quit_button.texture_normal = tex_quit
        
        header.add_child( quit_button )
#        quit_button.set_owner( header ) 
        quit_button.connect ( "pressed", self, "_on_Quit_pressed" )
    ###
    # close
    var close_button = TextureButton.new()
    if not header.has_node( "close" ):
        close_button = TextureButton.new()
        close_button.name = "close"
        close_button.size_flags_horizontal = SIZE_SHRINK_END
        close_button.size_flags_vertical = SIZE_SHRINK_CENTER
        
        var tex_close = ImageTexture.new()
        var img_close = Image.new()
        img_close.load( "res://assets/GUI/images/button_close.png" )
        tex_close.create_from_image( img_close )
        close_button.texture_normal = tex_close
        
        header.add_child( close_button )
#        close_button.set_owner( header ) 
        close_button.connect ( "pressed", self, "_on_Close_pressed" )
    ###
    # open
    var open_button
    if not header.has_node( "open" ):
        open_button = TextureButton.new()
        open_button.name = "open"
        open_button.size_flags_horizontal = SIZE_SHRINK_END
        open_button.size_flags_vertical = SIZE_SHRINK_CENTER
        
        var tex_open = ImageTexture.new()
        var img_open = Image.new()
        img_open.load( "res://assets/GUI/images/button_open.png" )
        tex_open.create_from_image( img_open )
        open_button.texture_normal = tex_open
        open_button.visible = false
        header.add_child( open_button )
#        open_button.set_owner( header ) 
        open_button.connect ( "pressed", self, "_on_Open_pressed" )
    ###
    ###
    # Title Label
    var title_label
    if not header.has_node( "label" ):
        title_label = Label.new()
        title_label.name = "label"
        title_label.text = title
        title_label.size_flags_horizontal = SIZE_EXPAND_FILL
        title_label.size_flags_vertical = SIZE_SHRINK_CENTER
        if is_movable:
            title_label.mouse_default_cursor_shape = CURSOR_MOVE
        header.add_child( title_label )
#        title_label.set_owner( header ) 
    ###
    ###
    # Content
    var content_box
    if not parts.has_node( "content_box" ):
        content_box = MarginContainer.new()
        content_box.name = "content_box"
        content_box.size_flags_horizontal = SIZE_EXPAND_FILL
        content_box.size_flags_vertical = SIZE_EXPAND_FILL
        content_box.set( "custom_constants/margin_right", 8)
        content_box.set( "custom_constants/margin_top", 8)
        content_box.set( "custom_constants/margin_left", 8)
        content_box.set( "custom_constants/margin_bottom", 8)
        parts.add_child( content_box )
#        content_box.set_owner( parts ) 
    ### 
    ###
    # content_box/scroll_container
    var content_scroll_container
    if not content_box.has_node( "scroll_container" ):
        content_scroll_container = ScrollContainer.new()
        content_scroll_container.name = "scroll_container"
        content_scroll_container.size_flags_horizontal = SIZE_FILL
        content_scroll_container.size_flags_vertical = SIZE_FILL
        content_scroll_container.scroll_deadzone = 0
        content_box.add_child( content_scroll_container )
#        content_scroll_container.set_owner( content_box ) 
    ###
    ###
    # content
    var content
    if not content_scroll_container.has_node( "content" ):
        content = VBoxContainer.new()
        content.name = "content"
        content.size_flags_horizontal = SIZE_EXPAND_FILL
        content.size_flags_vertical = SIZE_EXPAND_FILL
        content_scroll_container.add_child( content )
#        content.set_owner( content_scroll_container ) 
    ### 
        
         
    ###
    # Footer
    var footer_box
    if not parts.has_node( "footer_box" ):
        footer_box = MarginContainer.new()
        footer_box.name = "footer_box"
        footer_box.size_flags_horizontal = SIZE_FILL
        footer_box.size_flags_vertical = SIZE_FILL
        footer_box.set( "custom_constants/margin_right", content_margin.position.y)
        footer_box.set( "custom_constants/margin_top", content_margin.size.x)
        footer_box.set( "custom_constants/margin_left", content_margin.position.x)
        footer_box.set( "custom_constants/margin_bottom", content_margin.size.y)
        parts.add_child( footer_box )
#        footer_box.set_owner( parts ) 
        ###  
    ###
    # footer_box/footer
    var footer
    if not footer_box.has_node( "footer" ):
        footer = HBoxContainer.new()
        footer.name = "footer"
        footer.size_flags_horizontal = SIZE_EXPAND_FILL
        footer.size_flags_vertical = SIZE_EXPAND_FILL
        footer_box.add_child( footer )
#        footer.set_owner( footer_box ) 
    ###
    ###
    # footer_label
    var footer_label
    if not footer.has_node( "footer_label" ):
        footer_label = Label.new()
        footer_label.name = "footer_label"
        footer_label.size_flags_horizontal = SIZE_EXPAND
        footer_label.size_flags_vertical = SIZE_EXPAND

        footer.add_child( footer_label )

    ###
    # resize
    var resize_button
    if not footer.has_node( "resize" ):
        resize_button = TextureButton.new()
        resize_button.name = "resize"
        resize_button.size_flags_horizontal = SIZE_FILL | SIZE_SHRINK_END
        resize_button.size_flags_vertical = SIZE_SHRINK_END
        
        var tex_resize = ImageTexture.new()
        var img_resize = Image.new()
        img_resize.load( "res://assets/GUI/images/button_resize.png" )
        tex_resize.create_from_image( img_resize )
        resize_button.texture_normal = tex_resize
        resize_button.mouse_default_cursor_shape = CURSOR_FDIAGSIZE
        resize_button.action_mode = Button.ACTION_MODE_BUTTON_PRESS 
        footer.add_child( resize_button )
#        resize_button.set_owner( footer ) 
        resize_button.connect ( "pressed", self, "_on_Resize_pressed" )
    ###er_label.set_owner( footer ) 
    ###
        
    current_rect_size = self.rect_min_size
    
    if is_borderless:
        $background.region_rect = Rect2( $background.patch_margin_left-1
                                       , $background.patch_margin_top-1
                                       , 256-($background.patch_margin_left+$background.patch_margin_right)+2
                                       , 256-($background.patch_margin_top+$background.patch_margin_bottom)+2 ) 
        $background.patch_margin_left = 1
        $background.patch_margin_top = 1
        $background.patch_margin_right = 1
        $background.patch_margin_bottom = 1
        header_box.rect_min_size.y = 1
        close_button.visible = false
        open_button.visible = false
        quit_button.visible = false
        title_label.visible = false
        
        
        
        
    if not is_resizable:
        if not has_footer:
            footer_box.visible = false
        else:
            footer_box.get_node( "footer/resize" ).visible = false

func _ready():
    # On déplace les enfants ajouter via l'editeur sous content.
    for child in self.get_children():
        if not child.name =="parts" and not child.name =="background":
            if child.name.begins_with( "footer_" ):
                if footer_box.get_node("footer").has_node("footer_label"):
                    footer_box.get_node("footer").remove_child( footer_box.get_node("footer").get_node("footer_label") )
                
                self.remove_child( child )
                get_footer().add_child( child )
                get_footer().move_child( child, 0 )
            else:
                self.remove_child( child )
                get_content().add_child( child )
    
    set_mouse_pass_to_children( self )
    
func _process(delta):
    if size_changed:
        self.rect_size = Vector2( clamp( self.rect_size.x, min_size.x, self.rect_size.x ), clamp( self.rect_size.y, min_size.y, self.rect_size.y ) )
        size_changed = false
    
func _on_Window_mouse_entered():
    print("mouse_entered")


func _on_Window_focus_entered():
    print("focus_entered")


func _on_Quit_pressed():
    self.visible = false

func get_content():
    return content_box.get_node( "scroll_container/content" )

func get_footer():
    return footer_box.get_node( "footer" )


func close():
    if not is_borderless:
        header_box.get_node( "header/close" ).visible = false
        header_box.get_node( "header/open" ).visible = true
        content_box.visible = false
        footer_box.visible = false
        current_rect_size = self.rect_size
        self.rect_size = Vector2( 0, 0 )
    else:
        header_box.get_node( "header/close" ).visible = false
        header_box.get_node( "header/open" ).visible = false
        content_box.visible = false
        footer_box.visible = false
        current_rect_size = self.rect_size
        self.rect_size = Vector2( 0, 0 )
        
        
func _on_Close_pressed():
    close()

func open():
    if not is_borderless:
        header_box.get_node( "header/close" ).visible = true
        header_box.get_node( "header/open" ).visible = false
        content_box.visible = true
        footer_box.visible = true
        self.rect_size = current_rect_size
    else:
        header_box.get_node( "header/close" ).visible = false
        header_box.get_node( "header/open" ).visible = false
        content_box.visible = true
        footer_box.visible = true
        self.rect_size = current_rect_size
        
func _on_Open_pressed():
    open()

func _on_Resize_pressed():
    is_resizing = true

func _input( event ):
    if is_resizable: 
        if is_resizing and event is InputEventMouseButton and not event.pressed:
            is_resizing = false
        if event is InputEventMouseMotion and is_resizing:
            var delta = event.relative
            self.rect_size += delta
            size_changed = true
            
func check_if_clicked( event ):
    if not is_moving and event is InputEventMouseButton and event.is_pressed() and not event.is_echo() and event.button_index == 1 :
        emit_signal( "window_clicked", self )
        
func _on_Header_gui_input( event ):
    
    check_if_clicked( event )
    
    if is_movable:        
        if is_moving and event is InputEventMouseButton and not event.pressed:
            is_moving = false  
        elif not is_moving and event is InputEventMouseButton and event.pressed:
            is_moving = true 
        if event is InputEventMouseMotion and is_moving:
            var delta = event.relative
            self.rect_position += delta

func _on_window_gui_input( event ):
    check_if_clicked( event )
    
func load_from_file( config_file ):
    if config_file.has_section( self.name ):
        self.rect_position = config_file.get_value( self.name, "position" )
        self.rect_size = config_file.get_value( self.name, "size" )
        self.is_borderless = config_file.get_value( self.name, "borderless" )
        current_rect_position = self.rect_position
        current_rect_size = self.rect_size
        if config_file.get_value( self.name, "opened" ):
            open()
        else:
            close()


func save_to_file( config_file ):
    
    var is_open = content_box.visible

    config_file.set_value(self.name, "position", self.rect_position)
    
    if not is_open:
        config_file.set_value(self.name, "size", current_rect_size)
    else:
        config_file.set_value(self.name, "size", self.rect_size)
        
    if is_open:
        config_file.set_value(self.name, "opened", true)
    else:
        config_file.set_value(self.name, "opened", false)
        
    config_file.set_value(self.name, "borderless", is_borderless)