class Booklet extends this.OS.application.BaseApplication
    constructor: ( args ) ->
        super "Booklet", args
    
    main: () ->
        
        @tree = @find "toc-ui"
        @currentToc = undefined
        @dirty = false
        @emux = false
        @on "treeselect", (evt) =>
            e = evt.data.item.data
            return @reloadEditor() if (@currentToc is e) or (e is undefined) or (e.treepath is 0)
            e.treepath = e.path
            @load(e).then ()=>
                @open e
            .catch (msg) =>
                e.loaded = true
                @open e
                @error __("Error when loading '{0}': {1}", e.text, msg.toString()), msg
        
        @tree.ondragndrop = (e) =>
            @dndhandle(e)
        
        @initEditor()
        @resizeContent()
        @tree.contextmenuHandle = (e, m) =>
            menus = @contextMenu()
            return unless menus
            m.items = menus
            m.onmenuselect = (evt) =>
                @[evt.data.item.data.dataid]()
            m.show e
        @editor.codemirror.on "change", () =>
            return if @emux
            return unless @currentToc
            @currentToc.descFile.dirty = true
            @dirty = true
    
    newChapter: () ->
        return @error __("No book selected") unless @currentToc and @currentToc.type is "Book"
        ch = new BookletChapter(@book)
        @displayToc()
        ch.treepath = ch.path
    
    newSection: () ->
        return @error __("No chapter selected") unless @currentToc and @currentToc.type is "Chapter"
        sec = new BookletSection(@currentToc)
        @displayToc()
        sec.treepath = sec.path
    
    newFile: () ->
        return @error __("No section selected") unless @currentToc and @currentToc.type is "Section"
        file = new BookletFile(@currentToc)
        @displayToc()
        file.treepath = file.path
    
    delete: () ->
        
        return @error __("No entrie select") unless @currentToc
        fn = () =>
            @currentToc = undefined
            @displayToc()
            @reloadEditor()
        @currentToc.remove().then () =>
            @notify __("Entrie deleted")
            fn()
        .catch (e) =>
            @error e.toString(), e
            fn()
    
    goUp: () ->
        return unless @currentToc and @currentToc.type isnt "Book"
        @currentToc.parent.up @currentToc
        @displayToc()
    
    goDown: () ->
        return unless @currentToc and @currentToc.type isnt "Book"
        @currentToc.parent.down @currentToc
        @displayToc()
    
    load: (entry) ->
        
        return new Promise (r, e) =>
            return r() if entry.loaded
            entry.descFile.meta().then (d) =>
                entry.descFile.read().then (data) =>
                    entry.descFile.cache = data
                    entry.loaded = true
                    entry.descFile.dirty = false
                    r()
                .catch (msg) -> e __e msg
            .catch (msg) -> e __e msg
                    
    
    dndhandle: (e) ->
        return unless e and e.data
        from = e.data.from[0].data
        to = e.data.to.data
        return unless from and to
        return if from.type is "Book" or from.type is "Chapter"
        return if from.parent is to.parent or from.parent is to
        if to.type is from.type
            to = to.parent
        
        if to.type is from.parent.type
            from.parent.removeChild(from).then () =>
                to.add from
                @displayToc()
    
    upload: () ->
        return unless @currentToc and @currentToc.type isnt "File"
        @currentToc.path.asFileHandle().upload()
        .then () =>
            @notify __("File uploaded")
        .catch (e) =>
            @error __("Unable to upload file {0}", e.toString()), e
    
    contextMenu: () ->
        return undefined unless @currentToc
        switch @currentToc.type
            when "Book"
                return [
                    { text: __("New chapter"), dataid: "newChapter" },
                    { text: __("Delete book"), dataid: "delete" },
                    { text: __("Upload media"), dataid: "upload" }
                ]
            when "Chapter"
                return [
                    { text: __("New section"), dataid: "newSection" },
                    { text: __("Delete chapter"), dataid: "delete" },
                    { text: __("Go up"), dataid: "goUp" },
                    { text: __("Go down"), dataid: "goDown" },
                    { text: __("Upload media"), dataid: "upload" }
                ]
            when "Section"
                return [
                    { text: __("New file"), dataid: "newFile" },
                    { text: __("Delete section"), dataid: "delete" },
                    { text: __("Go up"), dataid: "goUp" },
                    { text: __("Go down"), dataid: "goDown" },
                    { text: __("Upload media"), dataid: "upload" }
                ]
            when "File"
                return [
                    { text: __("Delete file"), dataid: "delete" },
                    { text: __("Go up"), dataid: "goUp" },
                    { text: __("Go down"), dataid: "goDown" }
                ]
        return undefined
    
    shareFile: (mimes,f) ->
        
        @openDialog "FileDialog", { title: __("Select a file"), mimes: mimes }
        .then (d) =>
            d.file.path.asFileHandle().publish().then (r) ->
                f r.result
            .catch (msg) =>
                return @error __("Cannot export file for embedding to text"), msg
        .catch (msg) =>
                return @error msg.toString(), msg
                
    initEditor: ()->
        markarea = @find "markarea"
        @container = @find "mycontainer"
        @previewOn = false
        @editormux = false
        
        @editor = new SimpleMDE
            element: markarea
            autoDownloadFontAwesome: false
            autofocus: true
            tabSize: 4
            indentWithTabs: true
            toolbar: [
                "bold", "italic", "heading", "|", "quote", "code",
                "unordered-list", "ordered-list", "|", "link",
                "image", "table", "horizontal-rule",
                {
                    name: "shared image",
                    className: "fa fa-share-square",
                    action: (e) =>
                        @shareFile ["image/.*"], (path) =>
                            doc = @editor.codemirror.getDoc()
                            doc.replaceSelection "![](#{@_api.handler.shared}/#{path})"
                },
                {
                    name: "local image",
                    className: "fa fa-file-image-o",
                    action: (e) =>
                        return unless @book
                        @openDialog "FileDialog", {
                            title: __("Select image file"),
                            mimes: ["image/.*"],
                            root: @book.path
                        }
                        .then (d) =>
                            path = d.file.path.replace @book.path, ""
                            doc = @editor.codemirror.getDoc()
                            #selectedText =  @editor.codemirror.getSelection() 
                            doc.replaceSelection "[[@book:image:#{path}]]"
                        .catch (e) =>
                            @error e.toString(), e
                },
                {
                    name:"Youtube",
                    className: "fa fa-youtube",
                    action: (e) =>
                        doc = @editor.codemirror.getDoc()
                        selectedText =  @editor.codemirror.getSelection() || ""
                        doc.replaceSelection "[[youtube:#{selectedText}]]"
                },
                {
                    name: "3d object",
                    className: "fa fa-cube",
                    action: (e) =>
                        return unless @book
                        @openDialog "FileDialog", {
                            title: __("Select 3d model"),
                            mimes: ["text/wavefront-obj", "model/gltf-binary"],
                            root: @book.path
                        }
                        .then (d) =>
                            path = d.file.path.replace @book.path, ""
                            doc = @editor.codemirror.getDoc()
                            doc.replaceSelection "[[@book:3dmodel:#{path}]]"
                        .catch (e) =>
                            @error e.toString(), e
                },
                "|",
                {
                    name: __("Preview"),
                    className: "fa fa-eye no-disable",
                    action: (e) =>
                        SimpleMDE.togglePreview e
                        #/console.log @select ".editor-preview editor-preview-active"
                        renderMathInElement @find "mycontainer"
                        @renderLocalElement()
                }
            ],
            previewRender: (plainText, preview) =>
                if @book
                    plainText = plainText.replace /\[\[@book:image:([^\]]*)\]\]/g, (a, b) =>
                        return "![](#{@_api.handle.get}/#{@book.path}/#{b})"
                html = @editor.markdown plainText
                
                preview.innerHTML = html
        
        @on "hboxchange", (e) => @resizeContent()
        @bindKey "ALT-N", () => @actionFile "#{@name}-New"
        @bindKey "ALT-O", () => @actionFile "#{@name}-Open"
        @bindKey "CTRL-S", () => @actionFile "#{@name}-Save"
        
    reloadEditor: () ->
        if @currentToc is undefined
            @editor.value ""
            return @scheme.apptitle = @name
        @editor.value @currentToc.descFile.cache || ""
        @scheme.apptitle = "Booklet - #{@currentToc.descFile.path}"
    
    saveContext: () ->
        return unless @currentToc
        @currentToc.descFile.cache = @editor.value()

    resizeContent: () ->
        children = ($ @container).children()
        titlebar = (($ @scheme).find ".afx-window-top")[0]
        toolbar = children[1]
        statusbar = children[4]
        cheight = ($ @scheme).height() - ($ titlebar).height() - ($ toolbar).height() - ($ statusbar).height() - 40
        ($ children[2]).css("height", cheight + "px")


    menu: () ->
        
        menu = [{
                text: "__(File)",
                nodes: [
                    { text: "__(New booklet)", dataid: "#{@name}-New", shortcut: "A-N" },
                    { text: "__(Open a booklet)", dataid: "#{@name}-Open", shortcut: "A-O" }
                    { text: "__(Save a booklet)", dataid: "#{@name}-Save", shortcut: "C-S" }
                ],
                onchildselect: (e) => @actionFile e.data.item.data.dataid
            }]
        menu
    
    actionFile: (e) ->
        
        switch e
            when "#{@name}-Open"
                @checkForDirty () =>
                    @openDialog "FileDialog", { title:__("Open book"), mimes: ['dir'] }
                    .then (d) =>
                        @book = new BookletBook(d.file.path)
                        @book.read(d.file.path).then () =>
                            @book.treepath = @book.path
                            @tree.selectedItem = undefined
                            @displayToc()
                            @notify __("Book loaded")
                        .catch (msg) =>
                            @error __("Cannot load book: {0}", msg.toString()), msg
                    .catch (msg) => @error msg.toString(), msg
                   
             when "#{@name}-New"
                @openDialog "FileDialog", { title: __("New book at"), mimes: ['dir'], file: { basename: __("BookName") }}
                .then (d) =>
                    @newAt "#{d.file.path}/#{d.name}"
                .catch (msg) => @error msg.toString(), msg
            when "#{@name}-Save"
                return unless @book
                @saveContext() if @currentToc
                @displayToc()
                @book.save().then () =>
                    @dirty = false
                    @notify __("Book saved")
                .catch (e) =>
                    @error __("Can't save the book : {0}", e.toString()), e
    
    checkForDirty: (f) ->
        return f() unless @dirty
        @ask {title: __("Continue ?"), text: __("Book is unsaved, you want to continue ?") }
        .then (d) =>
            # console.log d
            if d
                f()
        
    
    open: (toc) ->
        @emux = true
        @saveContext()
        @currentToc  = toc
        @reloadEditor()
        @displayToc()
        @emux = false

    
    newAt: (folder) ->
        @tree.selectedItem = undefined
        @book = new BookletBook(folder)
        @book.treepath = @book.path
        @currentToc = undefined
        @reloadEditor()
        @displayToc()
    
    displayToc: () ->
        @book.toc()
        @tree.data = @book
        @tree.expandAll()
    
    cleanup: (evt) ->
        return unless @dirty
        evt.preventDefault()
        @checkForDirty () =>
            @dirty = false
            @quit()
    
    renderLocalElement: () ->
        
    
Booklet.dependencies = [
    "pkg://SimpleMDE/main.js",
    "pkg://SimpleMDE/main.css",
    "pkg://Katex/main.js",
    "pkg://Katex/main.css"
]

this.OS.register "Booklet", Booklet