"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var MooBase_1 = require("./base/MooBase");
var CreateDOM_1 = require("../utils/CreateDOM");
var StickyNote_1 = require("./StickyNote");
var Listen_1 = require("../utils/Listen");
var types_1 = require("../types");
var TypeRecognizer_1 = require("../utils/TypeRecognizer");
// TODO structure redesign;
var Tab = /** @class */ (function (_super) {
    __extends(Tab, _super);
    function Tab(header, id, filename, _isFixedTemplate) {
        var _this = _super.call(this, header.innerHeader) || this;
        _this._isFixedTemplate = _isFixedTemplate;
        if (!_this._isFixedTemplate) {
            _this._closeButton = CreateDOM_1.CreDOM.createDOM('div', 'r-board-tab-close');
            _this._closeButton.innerText = 'x';
            _this.ele.appendChild(_this._closeButton);
        }
        _this._id = id;
        _this.ele.id = 'rt-' + _this._id;
        _this._text.innerText = filename;
        _this._filename = filename;
        return _this;
    }
    Tab.prototype._createElement = function () {
        var el = CreateDOM_1.CreDOM.createDOM('div', 'r-board-tab');
        this._text = CreateDOM_1.CreDOM.createDOM('div', 'r-board-tab-text');
        el.appendChild(this._text);
        return el;
    };
    Tab.prototype.eliminate = function () {
        this._id = 0;
        this.ele.removeChild(this._text);
        this.ele.removeChild(this._closeButton);
        _super.prototype.eliminate.call(this);
    };
    Object.defineProperty(Tab.prototype, "id", {
        get: function () {
            return this._id;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tab.prototype, "textArea", {
        get: function () {
            return this._text;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tab.prototype, "closeButton", {
        get: function () {
            return this._closeButton;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tab.prototype, "text", {
        set: function (text) {
            this._text.innerText = text;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tab.prototype, "filename", {
        get: function () {
            return this._filename;
        },
        set: function (filename) {
            this._filename = filename;
        },
        enumerable: true,
        configurable: true
    });
    Tab.prototype.helloTextListener = function (callback) {
        this._helloListener(types_1.CLICK, callback, this._text);
    };
    Tab.prototype.helloCloseListener = function (callback) {
        this._helloListener(types_1.CLICK, callback, this._closeButton);
    };
    Tab.prototype.helloEditTextListener = function (callback) {
        this._helloListener(types_1.DbLCLICK, callback, this._text);
    };
    return Tab;
}(MooBase_1.MooBase));
var BoardHeader = /** @class */ (function (_super) {
    __extends(BoardHeader, _super);
    function BoardHeader(board, opt) {
        var _this = _super.call(this, board.headerContainer) || this;
        _this._isTabEditting = false;
        _this._isFixedTemplate = opt.isFixedTemplate ? true : false;
        _this._tabs = [];
        return _this;
    }
    BoardHeader.prototype._createElement = function () {
        var ih = CreateDOM_1.CreDOM.createDOM('div', 'r-board-inner-header');
        var h = CreateDOM_1.CreDOM.createDOM('div', 'r-board-header');
        this._innerHeader = ih;
        h.appendChild(ih);
        return h;
    };
    Object.defineProperty(BoardHeader.prototype, "currentID", {
        get: function () {
            return this._currentID;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BoardHeader.prototype, "innerHeader", {
        get: function () {
            return this._innerHeader;
        },
        enumerable: true,
        configurable: true
    });
    BoardHeader.prototype.getIdByFilename = function (filename) {
        var tabs = this._tabs;
        var len = tabs.length;
        for (var i = 0; i < len; i++) {
            if (tabs[i].filename === filename) {
                return tabs[i].id;
            }
        }
    };
    BoardHeader.prototype.helloTabListener = function (tab, textCB, closeCB, editCB) {
        tab.helloTextListener(textCB);
        if (!this._isFixedTemplate) {
            tab.helloCloseListener(closeCB);
        }
        tab.helloEditTextListener(editCB);
    };
    BoardHeader.prototype.selectTab = function (id) {
        var tabs = this._tabs;
        var len = tabs.length;
        if (this._currentID !== id) {
            for (var i = 0; i < len; i++) {
                if (tabs[i].id === this.currentID) {
                    tabs[i].ele.classList.remove('selected-tab');
                }
            }
            for (var i = 0; i < len; i++) {
                if (tabs[i].id === id) {
                    tabs[i].ele.classList.add('selected-tab');
                    this._currentID = tabs[i].id;
                }
            }
        }
    };
    BoardHeader.prototype.createTab = function (id, filename) {
        var tab = new Tab(this, id, filename, this._isFixedTemplate);
        this._tabs.push(tab);
        return tab;
    };
    BoardHeader.prototype.removeTab = function (id) {
        var tabs = this._tabs;
        var len = tabs.length;
        for (var i = 0; i < len; i++) {
            if (tabs[i].id === id) {
                tabs[i].eliminate();
                tabs.splice(i, 1);
                break;
            }
        }
    };
    BoardHeader.prototype.getFilenames = function () {
        var res = {};
        var tabs = this._tabs;
        var len = tabs.length;
        for (var i = 0; i < len; i++) {
            res[tabs[i].id] = tabs[i].filename;
        }
        return res;
    };
    BoardHeader.prototype.editTextUnder = function (id, callback) {
        if (this._isTabEditting) {
            return;
        }
        var tabs = this._tabs;
        var len = tabs.length;
        for (var i = 0; i < len; i++) {
            var tab = tabs[i];
            if (tab.id === id) {
                this._isTabEditting = true;
                tab.textArea.classList.add('invisible');
                tab.closeButton.classList.add('invisible');
                var textField = document.createElement('input');
                textField.className = 'r-textfield';
                this._textField = textField;
                tab.ele.appendChild(textField);
                textField.addEventListener(types_1.KEYUP, callback);
                this._edittingID = id;
            }
        }
    };
    BoardHeader.prototype.edittingTextUnder = function (callback) {
        var id = this._edittingID;
        var tfield = this._textField;
        var tabs = this._tabs;
        var len = tabs.length;
        var tab = null;
        for (var i = 0; i < len; i++) {
            var t = tabs[i];
            if (t.id === id) {
                tab = t;
                break;
            }
        }
        if (tab) {
            tab.text = tfield.value;
            tab.filename = tfield.value;
            tfield.removeEventListener(types_1.KEYUP, callback);
            tab.ele.removeChild(tfield);
            tab.textArea.classList.remove('invisible');
            tab.closeButton.classList.remove('invisible');
            this._isTabEditting = false;
            return tab.filename;
        }
    };
    BoardHeader.prototype.resizeEle = function () {
        var len;
        if (this._tabWidth !== undefined) {
            len = this._tabs.length * this._tabWidth;
        }
        else if (this._tabs[0]) {
            this._tabWidth = this._tabs[0].ele.offsetWidth;
            len = this._tabs.length * this._tabWidth;
        }
        else {
            len = 0;
        }
        this._innerHeader.style.width = len + 'px';
    };
    return BoardHeader;
}(MooBase_1.MooBase));
var Board = /** @class */ (function (_super) {
    __extends(Board, _super);
    function Board(CodeBoard, opt) {
        var _this = _super.call(this, CodeBoard.ele) || this;
        _this._idCount = 1;
        _this._stickyNotes = {};
        _this._isFixedTemplate = false; // later property를 바꿈으로써 모드 변경
        _this._isCreatingNote = false;
        _this._header = new BoardHeader(_this, opt);
        var isFixed = opt.isFixedTemplate;
        if (isFixed) {
            _this._isFixedTemplate = true;
        }
        else {
            _this._isFixedTemplate = false;
            var plusTab = document.createElement('div');
            _this._plusTab = plusTab;
            _this._plusTab.className = 'r-board-plus-tab';
            _this._plusTab.innerText = '+';
            _this._headerContainer.appendChild(plusTab);
            _this._helloListener(types_1.CLICK, _this._addButtonClick.bind(_this), _this._plusTab);
        }
        return _this;
    }
    Board.prototype._createElement = function () {
        var head = CreateDOM_1.CreDOM.createDOM('div', 'r-board-headcon');
        var body = CreateDOM_1.CreDOM.createDOM('div', 'r-board-bodycon');
        var board = CreateDOM_1.CreDOM.createDOM('div', 'r-board');
        this._headerContainer = head;
        this._bodyContainer = body;
        board.appendChild(head);
        board.appendChild(body);
        return board;
    };
    Object.defineProperty(Board.prototype, "selected", {
        get: function () {
            return this._selected || -1;
        },
        set: function (id) {
            this._selected = id;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Board.prototype, "headerContainer", {
        get: function () {
            return this._headerContainer;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * createPage
     */
    Board.prototype.createPage = function (lang, filename, code) {
        // id
        var id = this._idCount++;
        if (!this._stickyNotes[id]) {
            // stickyNote
            if (this._selected) {
                this._stickyNotes[this._selected].closeEditor();
            }
            var note = new StickyNote_1.StickyNote(id);
            note.createEditor(this._bodyContainer, lang, code);
            this._stickyNotes[id] = note;
            // tab
            var tab = this._header.createTab(id, filename);
            this._header.helloTabListener(tab, this._textClick.bind(this), this._closeButtonClick.bind(this), this._textEdit.bind(this));
            this._header.selectTab(id);
            this._selected = id;
        }
        else {
            throw new Error('already existing note!');
        }
    };
    /**
     * select
     *
     * @remarks
     * 해당 하는 id의 stickynote의 에디터를 열여준다.
     */
    Board.prototype.select = function (id) {
        var prevID = this._selected;
        this._selected = id;
        if (prevID === id) {
            return;
        }
        if (prevID) {
            this._stickyNotes[prevID].closeEditor();
        }
        if (id) {
            this._stickyNotes[id].openEditor(this._bodyContainer);
        }
    };
    /**
     * close
     *
     * @remarks
     * 해당하는 id에 관한 stickyNote를 없앤다.
     */
    Board.prototype.close = function (id) {
        if (id) {
            this._stickyNotes[id].removeEditor();
            delete this._stickyNotes[id];
            if (this._selected === id) {
                this._selected = 0;
            }
        }
    };
    /**
     * 탭의 텍스트 클릭
     */
    Board.prototype._textClick = function (event) {
        var id = Listen_1.getParentDOMID(event);
        if (id === -1) {
            return;
        }
        // tab select
        this._header.selectTab(id);
        // editor select
        this.select(id);
    };
    /**
     * 닫기 버튼 클릭
     */
    Board.prototype._closeButtonClick = function (event) {
        var id = Listen_1.getParentDOMID(event);
        // tab remove
        this._header.removeTab(id);
        // editor remove
        this.close(id);
        this._header.resizeEle();
        this._relocateAddButton();
    };
    /**
     * 추가 버튼 클릭
     */
    Board.prototype._addButtonClick = function (event) {
        if (!this._isCreatingNote) {
            this._isCreatingNote = true;
            this._editText(this._idCount);
            this._header.resizeEle();
            this._relocateAddButton();
        }
    };
    /**
     * 추가버튼 재위치
     */
    Board.prototype._relocateAddButton = function () {
        this._plusTab.style.left = this._header.ele.offsetWidth + 'px';
    };
    /**
     * id를 얻고 파일이름 수정
     */
    Board.prototype._textEdit = function (event) {
        // const id = getParentDOMID(event);
        // this._editText(id)
    };
    /**
     * id 따른 파일이름 수정
     */
    Board.prototype._editText = function (id) {
        var tab = this._header.createTab(id, 'default.js');
        this._header.editTextUnder(id, this._edittingText.bind(this));
        this._targetTab = tab;
    };
    Board.prototype._edittingText = function (event) {
        var code = event.keyCode;
        if (code === 13) {
            var filename = this._header.edittingTextUnder(this._edittingText.bind(this));
            var lang = '';
            lang = TypeRecognizer_1.langDeterminer(filename);
            // stickyNote
            var id = this._idCount++;
            if (this._selected) {
                this._stickyNotes[this._selected].closeEditor();
            }
            var note = new StickyNote_1.StickyNote(id);
            note.createEditor(this._bodyContainer, lang);
            this._stickyNotes[id] = note;
            // tab
            var tab = this._targetTab;
            this._header.helloTabListener(tab, this._textClick.bind(this), this._closeButtonClick.bind(this), this._textEdit.bind(this));
            this._header.selectTab(id);
            this._selected = id;
            this._isCreatingNote = false;
            console.log(lang + ' editor made!');
        }
    };
    /**
     * Add file with blank tab
     */
    Board.prototype.addBlankFile = function () {
        if (!this._isFixedTemplate) {
            this._addButtonClick();
        }
    };
    /**
     * Add File
     */
    Board.prototype.addFile = function (filename, content) {
        var type = TypeRecognizer_1.langDeterminer(filename);
        this.createPage(type, filename, content);
        this._header.resizeEle();
        this._relocateAddButton();
    };
    /**
     * Add Files
     */
    Board.prototype.addFiles = function (filenames) {
        var len = filenames.length;
        for (var i = 0; i < len; i++) {
            // this.addFile(filenames[i], false);
            setTimeout(this.addFile.bind(this, filenames[i]), 0.01);
        }
    };
    /**
     * parse File
     */
    Board.prototype.parseFile = function (filename, content) {
        var type = TypeRecognizer_1.langDeterminer(filename);
        this.createPage(type, filename, content);
        this._header.resizeEle();
    };
    /**
     * parse and add Files
     */
    Board.prototype.parseFiles = function (files) {
        for (var filename in files) {
            setTimeout(this.parseFile.bind(this, filename, files[filename].content), 0.01);
        }
    };
    /**
     * Remove file
     */
    Board.prototype.removeFile = function (filename, reloca) {
        var id = this._header.getIdByFilename(filename);
        if (id) {
            this._header.removeTab(id);
            this.close(id);
            if (reloca) {
                this._header.resizeEle();
                this._relocateAddButton();
            }
        }
    };
    /**
     * Remove files
     */
    Board.prototype.removeFiles = function (filenames) {
        var len = filenames.length;
        for (var i = 0; i < len; i++) {
            this.removeFile(filenames[i], false);
        }
        this._header.resizeEle();
        this._relocateAddButton();
    };
    /**
     * get files
     */
    Board.prototype.getFiles = function () {
        var files = {};
        var filenames = this._header.getFilenames();
        for (var id in filenames) {
            var code = void 0;
            if (this._selected === Number(id)) {
                code = this._stickyNotes[id].saveCode();
            }
            else {
                code = this._stickyNotes[id].getCode();
            }
            var content = { content: code };
            files[filenames[id]] = content;
        }
        return files;
    };
    return Board;
}(MooBase_1.MooBase));
exports.Board = Board;
