/**
 * 导出PDF插件
 * @author  life life@leanote.com
 * 选择目录, 将图片保存到文件夹中, 有个html文件(以笔记名命名)
 * 注意, fs.existsSync总返回false, readFileSync可用
 */
define(function() {
    var async; // = require('async');

    var exportPDF = {
        langs: {
            'en-us': {
                'export': 'Export PDF',
                'Exporting': 'Exporting',
                'Exporting: ': 'Exporting: ',
                'exportSuccess': 'PDF saved successful!',
                'exportFailure': 'PDF saved failure!',
            },
            'de-de': {
                'export': 'Als PDF exportieren',
                'Exporting': 'Exportiere',
                'Exporting: ': 'Exportiere: ',
                'exportSuccess': 'PDF erfolgreich gespeichert!',
                'exportFailure': 'PDF speichern fehlgeschlagen!',
            },
            'zh-cn': {
                'export': '导出PDF',
                'Exporting': '正在导出',
                'Exporting: ': '正在导出: ',
                'exportSuccess': 'PDF导出成功!',
                'exportFailure': 'PDF导出失败!'
            },
            'zh-hk': {
                'export': '導出PDF',
                'Exporting': '正在導出',
                'Exporting: ': '正在導出: ',
                'exportSuccess': 'PDF導出成功!',
                'exportFailure': 'PDF導出失敗!'
            }
        },

        _inited: false,
        init: function() {
            var me = this;
            if (me._inited) {
                return;
            }
            async = require('async');
            me._inited = true;
            me._initExportPdf();
        },

        // 调用main导出pdf
        _exportPdfSeq: 1,
        _exportPdfCallback: {},
        _initExportPdf: function() {
            var me = this;
            // console.log('_initExportPdf');
            Api.ipc.on('export-pdf-ret', function(event, arg) {
                var seq = arg.seq;
                // console.log('export-pdf-ret');
                // console.log(arg);
                // console.log(me._exportPdfCallback[seq]);
                if (me._exportPdfCallback[seq]) {
                    me._exportPdfCallback[seq](arg);
                }
            });
        },
        exportPdf: function(htmlPath, targetPdfPath, isMarkdown, callback) {
            this._exportPdfSeq++;
            this._exportPdfCallback[this._exportPdfSeq] = callback;
            Api.ipc.send('export-pdf', { htmlPath: htmlPath, targetPdfPath: targetPdfPath, isMarkdown: isMarkdown, seq: this._exportPdfSeq });
        },

        getPluginPath: function() {
            return Api.evtService.getProjectBasePath() + '/public/plugins/export_pdf';
        },

        htmlTpl: '',
        markdownTpl: '',
        getTpl: function(isMarkdown) {
            var tpl = isMarkdown ? this.markdownTpl : this.htmlTpl;
            if (tpl) {
                return tpl;
            }
            var basePluginPath = this.getPluginPath();

            var tplName = isMarkdown ? 'markdown' : 'html';
            var tplPath = basePluginPath + '/tpl/' + tplName + '.tpl';
            tpl = Api.NodeFs.readFileSync(tplPath, 'utf-8');
            isMarkdown ? (this.markdownTpl = tpl) : (this.htmlTpl = tpl);
            return tpl;
        },
        // 生成html或markdown
        render: function(note) {
            var tpl = this.getTpl(note.IsMarkdown);
            var title = note.Title || getMsg('Untitled');
            tpl = tpl.replace(/\{title\}/g, title);
            tpl = tpl.replace("{content}", function() {
                return note.Content; // 为什么要这样? 因为 $$ 替换后变成了一个!!
            });
            return tpl;
        },

        replaceAll: function(src, pattern, to) {
            if (!src) {
                return src;
            }
            while (true) {
                var oldSrc = src;
                src = src.replace(pattern, to);
                if (oldSrc === src) {
                    return src;
                }
            }
        },

        fixFilename: function(filename) {
            var reg = new RegExp("/|#|\\$|!|\\^|\\*|'| |\"|%|&|\\(|\\)|\\+|\\,|/|:|;|<|>|=|\\?|@|\\||\\\\", 'g');
            filename = filename.replace(reg, "-");
            // 防止出现两个连续的-
            while (filename.indexOf('--') != -1) {
                filename = this.replaceAll(filename, '--', '-');
            }
            if (filename.length > 1) {
                // 最后一个-
                filename = filename.replace(/\-$/, '');
            }
            return filename;
        },

        // 得到可用的文件名, 避免冲突
        getPdfFilePath: function(pathInfo, n, cb) {
            var me = this;
            if (n > 1) {
                pathInfo.nameNotExt = pathInfo.nameNotExtRaw + '-' + n;
            }
            var absPath = pathInfo.getFullPath();

            // Api.NodeFs.existsSync(absPath) 总是返回false, 不知道什么原因
            // 在控制台上是可以的
            Api.NodeFs.exists(absPath, function(exists) {
                if (!exists) {
                    cb(absPath);
                } else {
                    me.getPdfFilePath(pathInfo, n + 1, cb);
                }
            });
        },

        getTargetPath: function(callback) {
            // showSaveDialog 不支持property选择文件夹
            var po = Api.gui.dialog.showOpenDialog(Api.gui.getCurrentWindow(), {
                defaultPath: Api.getDefaultPath(),
                properties: ['openDirectory']
            });
            if (typeof(po) != "object") {
                return;
            }

            po.then(function(re) {
                if (re.canceled !== false || re.filePaths.length < 1) {
                    return callback();
                }
                Api.saveLastPath(re.filePaths[0])
                callback(re.filePaths[0]);
            });
        },

        loadingIsClosed: false,

        exportPDFForNotebook: function(notebookId) {
            var me = this;
            if (!notebookId) {
                return;
            }
            me.getTargetPath(function(targetPath) {
                if (!targetPath) {
                    return;
                }

                me.loadingIsClosed = false;
                Api.loading.show(Api.getMsg('plugin.export_pdf.Exporting'), {
                    hasProgress: true,
                    isLarge: true,
                    onClose: function() {
                        me.loadingIsClosed = true;
                        setTimeout(function() {
                            me.hideLoading();
                        });
                    }
                });
                Api.loading.setProgress(1);

                Api.noteService.getNotes(notebookId, function(notes) {
                    if (!notes) {
                        me.hideLoading();
                        return;
                    }

                    var total = notes.length;
                    var i = 0;
                    async.eachSeries(notes, function(note, cb) {
                        if (me.loadingIsClosed) {
                            cb();
                            me.hideLoading();
                            return;
                        }
                        i++;
                        Api.loading.setProgress(100 * i / total);
                        me._exportPDF(note, targetPath, function() {
                            cb();
                        }, i, total);
                    }, function() {
                        me.hideLoading();
                        Notify.show({ title: 'Info', body: getMsg('plugin.export_pdf.exportSuccess') });
                    });
                });
            });
        },

        hideLoading: function() {
            setTimeout(function() {
                Api.loading.hide();
            }, 1000);
        },

        exportPDF: function(noteIds) {
            var me = this;
            if (!noteIds || noteIds.length == 0) {
                return;
            }
            me.getTargetPath(function(targetPath) {
                if (!targetPath) {
                    return;
                }

                me.loadingIsClosed = false;
                Api.loading.show(Api.getMsg('plugin.export_pdf.Exporting'), {
                    hasProgress: true,
                    isLarge: true,
                    onClose: function() {
                        me.loadingIsClosed = true;
                        setTimeout(function() {
                            me.hideLoading();
                        });
                    }
                });
                Api.loading.setProgress(1);

                var i = 0;
                var total = noteIds.length;

                async.eachSeries(noteIds, function(noteId, cb) {
                    if (me.loadingIsClosed) {
                        cb();
                        return;
                    }

                    i++;
                    Api.loading.setProgress(100 * i / total);
                    Api.noteService.getNote(noteId, function(note) {

                        me._exportPDF(note, targetPath, function(ok) {
                            cb();
                        }, i, total);
                    });

                }, function() {
                    me.hideLoading();
                    Notify.show({ title: 'Info', body: getMsg('plugin.export_pdf.exportSuccess') });
                });
            });
        },

        _exportPDF: function(note, path, callback, i, total) {
            var me = this;
            setTimeout(function() {
                me._exportPDF(note, path, callback, i, total);
            }, 1000);
        },

        _exportPDF: function(note, path, callback, i, total) {
            var me = this;
            if (!note) {
                return;
            }

            if (me.loadingIsClosed) {
                callback();
                return;
            }

            setTimeout(function() {
                Api.loading.setMsg(Api.getMsg('plugin.export_pdf.Exporting: ') + (note.Title || getMsg('Untitled')));
                Api.loading.setProgressRate(i + '/' + total);
            }, 100);

            var name = note.Title ? note.Title + '.pdf' : getMsg('Untitled') + '.pdf';
            name = me.fixFilename(name);

            var targetPath = path + Api.commonService.getPathSep() + name;

            // 将路径和名字区分开
            var pathInfo = Api.commonService.splitFile(targetPath);
            pathInfo.nameNotExt = me.fixFilename(pathInfo.nameNotExt); // 重新修正一次
            var nameNotExt = pathInfo.nameNotExt;
            pathInfo.nameNotExtRaw = pathInfo.nameNotExt;

            // 得到可用文件的绝对路径
            me.getPdfFilePath(pathInfo, 1, function(absPdfFilePath) {
                // 得到存放assets的目录
                var html = me.render(note);
                var tempPath = Api.gui.app.getPath('temp');
                var last = tempPath[tempPath.length - 1];
                if (last == '/' || last == '\\') {
                    tempPath = tempPath.substr(0, tempPath.length - 1);
                }
                var targetHtmlPath = tempPath + '/' + (new Date().getTime()) + '.html';

                // 把html文件写到tmp目录
                Api.commonService.writeFile(targetHtmlPath, html);
                me.exportPdf(targetHtmlPath, absPdfFilePath, note.IsMarkdown, function(args) {
                    // console.log('export pdf ret');
                    callback(args.ok);
                });
            });
        },

        // 打开前要执行的
        onOpen: function() {
            var me = this;
            var gui = Api.gui;

            var menu = {
                label: Api.getMsg('plugin.export_pdf.export'),
                enabled: function(noteIds) {
                    return true;
                },
                click: (function() {
                    return function(noteIds) {
                        me.init();
                        me.exportPDF(noteIds);
                    }
                })()
            };
            Api.addExportMenu(menu);

            Api.addExportMenuForNotebook({
                label: Api.getMsg('plugin.export_pdf.export'),
                enabled: function(notebookId) {
                    return true;
                },
                click: (function() {
                    return function(notebookId) {
                        me.init();
                        me.exportPDFForNotebook(notebookId);
                    }
                })()
            });
        },
        // 打开后
        onOpenAfter: function() {},
        // 关闭时需要运行的
        onClose: function() {}
    };

    return exportPDF;

});