//=============================================================================================================
// ** Filename          : DSI-BookSystem.js
// ** Last Updated      : Nov 18 2018
//=============================================================================================================
/*:
* @plugindesc v1.0 Release!
* @author dsiver144
* @help
* - Require DSI-WindowLayers to work properly.
* ------------------------------------------------------------------------------------
* > Script Calls:
* ------------------------------------------------------------------------------------
*  $gameSystem.unlockBookById(id)
*  ex: Unlock first book: $gameSystem.unlockBookById(0)
*
*  $gameSystem.unlockBookByName(name)
*  ex: $gameSystem.unlockBookByName('Test Book') // Unlock the book has 
*      name "Test Book"
* ------------------------------------------------------------------------------------
* > Conditional Branches Script Calls:
* ------------------------------------------------------------------------------------
*  $gameSystem.hasBookUnlockedById(id)
*  -> Use this to check if you have unlocked a specific book with their id.
*  $gameSystem.hasBookUnlockedByName(name)
*  -> Use this to check if you have unlocked a specific book with their name.
* ------------------------------------------------------------------------------------
* > Others:
* ------------------------------------------------------------------------------------
* Yanfly Main Menu Manager Main Bind: this.commandBook.bind(this)
* 
* @param Text 1
* @default Journal
* 
* @param Change Page SE
* @default {"name":"Book1","volume":"70","pitch":"100","pan":"0"}
* @type struct<SoundEffect>
* @desc This sound will be play when swapping pages.
* 
* @param Journal Config
* @type struct<JournalInfo>[]
* @default ["{\"Book Title\":\"Test Book\",\"Pages\":\"[\\\"{\\\\\\\"Text\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"This is text on page 1...\\\\\\\\\\\\\\\"\\\\\\\"}\\\",\\\"{\\\\\\\"Text\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"This is text on page 2...\\\\\\\\\\\\\\\"\\\\\\\"}\\\",\\\"{\\\\\\\"Text\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"This is text on page 3...\\\\\\\\\\\\\\\"\\\\\\\"}\\\"]\"}"]
*
*/
/*~struct~JournalInfo:
* @param Book Title
*
* @param Pages
* @type struct<JournalPage>[]
*/
/*~struct~JournalPage:
* @param Text
* @type note
*/
/*~struct~SoundEffect:
* @param name
* @type file
* @dir audio/se/
* 
* @param volume
* @default 70
*
* @param pitch
* @default 100
* 
* @param pan
* @default 0
*/

function Scene_DBook() {
    this.initialize.apply(this, arguments);
}

function Window_BookNameList() {
    this.initialize.apply(this, arguments);
}

function Window_BookDisplay() {
    this.initialize.apply(this, arguments);
}

var Imported = Imported || {};
Imported['DSI-BookSystem'] = 1.0;

(function(){
    
    var params = PluginManager.parameters('DSI-BookSystem');
    var changePageSE = JSON.parse(params['Change Page SE']);
    changePageSE.volume = Number(changePageSE.volume);
    changePageSE.pitch = Number(changePageSE.pitch);
    changePageSE.pan = Number(changePageSE.pan);
    
    console.log(changePageSE);
    
    var ConfigArray = JSON.parse(params['Journal Config']);
    var $bookData = [];
    var $bookIndexByName = {};
    for (var i = 0; i < ConfigArray.length; i++) {
        var book = JSON.parse(ConfigArray[i]);
        var pageArray = JSON.parse(book['Pages']);
        for (var j = 0; j < pageArray.length; j++) {
            pageArray[j] = JSON.parse(pageArray[j]);
            pageArray[j].Text = JSON.parse(pageArray[j].Text);
        }
        book['Pages'] = pageArray;
        $bookData.push(book);
        $bookIndexByName[book['Book Title']] = i;
    };
  
    var DSI_BookSystem_Game_System_initialize = Game_System.prototype.initialize;
    Game_System.prototype.initialize = function() {
        DSI_BookSystem_Game_System_initialize.apply(this, arguments);
        this._unlockedBooks = {}
    };
  
    Game_System.prototype.unlockBookById = function(index) {
        this._unlockedBooks[index] = true;
    };
  
    Game_System.prototype.unlockBookByName = function(name) {
        var index = $bookIndexByName[name];
        if (index === undefined) return false;
        this._unlockedBooks[index] = true;
        return true;
    };
    
    Game_System.prototype.hasBookUnlockedById = function(index) {
        return this._unlockedBooks[index];
    };
    
    Game_System.prototype.hasBookUnlockedByName = function(name) {
        var index = $bookIndexByName[name];
        if (index === undefined) return false;
        return this._unlockedBooks[index];
    };
    
    Game_System.prototype.displayBooks = function() {
        var that = this;
        return $bookData.filter(function (book, index) {return that.hasBookUnlockedById(index)});
    };
    
    Scene_Menu.prototype.commandBook = function() {
        SceneManager.push(Scene_DBook);
    };
    
    Scene_DBook.prototype = Object.create(Scene_MenuBase.prototype);
    Scene_DBook.prototype.constructor = Scene_DBook;
    
    Scene_DBook.prototype.create = function() {
        Scene_MenuBase.prototype.create.call(this);
        this.createAllWindows();
    };
    
    Scene_DBook.prototype.createAllWindows = function() {
        var ww = Graphics.width - 24 * 2;
        var wx = 24;
        var wy = 24;
        var wh = 72;
        this._titleWindow = new Window_Base(wx, wy, ww, wh);
        this._titleWindow.drawText(params['Text 1'], 0, 0, this._titleWindow.contentsWidth(), 'center');
        this.addWindow(this._titleWindow);
        
        wx = 24;
        wy = this._titleWindow.y + this._titleWindow.height + 24;
        wh = Graphics.height - this._titleWindow.y - this._titleWindow.height - 24 * 2;
        this._bookList = new Window_BookNameList(wx, wy, ww, wh);
        this.addWindow(this._bookList);
        
        this._bookDisplay = new Window_BookDisplay(wx, wy + 11, ww, wh);
        this._bookDisplay.opacity = 0;
        this._bookDisplay.backOpacity = 0;
        this._bookDisplay.contentsOpacity = 0;
        
        this.addWindow(this._bookDisplay);
        this._bookList.setHandler('ok', this.onBookOk.bind(this));
        this._bookList.setHandler('cancel', this.popScene.bind(this));
        
        this._maxOpacity = Moghunter ? Moghunter.mback_opacity : 255;
        this._opacityStep = Moghunter ? Moghunter.mback_opacity / 10 : 25;
        
        this._bookList.opacity = this._maxOpacity;
        
    };
    
    Scene_DBook.prototype.onBookOk = function() {
        var book = this._bookList.currentExt();
        this._bookDisplay.setBook(book);
        this._openBookFlag = true;
    };
    
    Scene_DBook.prototype.onBookCancel = function() {
        this._bookDisplay.hideArrows();
        this._closeBookFlag = true;
    };
    
    Scene_DBook.prototype.update = function() {
        Scene_MenuBase.prototype.update.call(this);
        if (this._openBookFlag) {
            if (this._bookList.opacity > 0) {
                this._bookList.opacity -= this._opacityStep;
                this._bookList.backOpacity -= this._opacityStep;
                this._bookList.contentsOpacity -= 25;
                this._bookList.y += 1;
            }
            if (this._bookDisplay.opacity < this._maxOpacity) {
                this._bookDisplay.opacity += this._opacityStep;
                if (this._bookDisplay.backOpacity < this._bookDisplay.standardBackOpacity()) this._bookDisplay.backOpacity += this._opacityStep;
                this._bookDisplay.contentsOpacity += 25;
                this._bookDisplay.y -= 1;
            }
            if (this._bookList.opacity === 0) {
                this._bookDisplay.updateBackOpacity();
                this._openBookFlag = false;
                this._bookOpen = true;
            }
        }
        if (this._closeBookFlag) {
            if (this._bookDisplay.opacity > 0) {
                this._bookDisplay.opacity -= this._opacityStep;
                this._bookDisplay.backOpacity -= this._opacityStep;
                this._bookDisplay.contentsOpacity -= 25;
                this._bookDisplay.y += 1;
            }
            if (this._bookList.opacity < this._maxOpacity) {
                this._bookList.opacity += this._opacityStep;
                if (this._bookList.backOpacity < this._bookList.standardBackOpacity()) this._bookList.backOpacity += this._opacityStep;
                this._bookList.contentsOpacity += 25;
                this._bookList.y -= 1;
            }
            if (this._bookDisplay.opacity === 0) {
                this._bookList.updateBackOpacity();
                this._closeBookFlag = false;
                this._bookOpen = false;
                this._bookList.activate();
            }
        }
        if (this._bookOpen) {
            if (Input.isRepeated('cancel') || TouchInput.isCancelled()) {
                SoundManager.playCancel();
                this.onBookCancel();
                return;
            }
            this._bookDisplay.updateChangePage();
        }
    };
    
    if (Imported['DSI-WindowLayers']) {
        Scene_DBook.prototype.createWindowLayer = function() {
            var width = Graphics.boxWidth;
            var height = Graphics.boxHeight;
            var x = (Graphics.width - width) / 2;
            var y = (Graphics.height - height) / 2;
            this._windowLayer = new WindowLayerEx();
            this._windowLayer.move(x, y, width, height);
            this.addChild(this._windowLayer);
        }
    };
    
    Window_BookNameList.prototype = Object.create(Window_Command.prototype);
    Window_BookNameList.prototype.constructor = Window_BookNameList;
    
    Window_BookNameList.prototype.initialize = function(x, y, width, height) {
        this.clearCommandList();
        this.makeCommandList();
        Window_Selectable.prototype.initialize.call(this, x, y, width, height);
        this.refresh();
        this.select(0);
        this.activate();
    };
    
    // For Compatible with MOG_MenuBackground
    Window_BookNameList.prototype.needUpdateBackOpacity = function() {
       return false;
    };
    
    Window_BookNameList.prototype.commandExt = function(index) {
        return this._list[index].ext;
    };
    
    Window_BookNameList.prototype.makeCommandList = function() {
        var data = $gameSystem.displayBooks();
        for (var i = 0; i < data.length; i++) {
            this.addCommand(data[i]['Book Title'], i, true, data[i]);
        }
    };

    Window_BookDisplay.prototype = Object.create(Window_Base.prototype);
    Window_BookDisplay.prototype.constructor = Window_BookDisplay;
    
    Window_BookDisplay.prototype.setBook = function(book) {
        this._book = book;
        this._pageIndex = 0;
        this._pageIndexMax = book.Pages.length - 1;
        this.refreshBook();
        // Add Event Listener To Arrow Sprites
        /*
        if (!this._addedEvents) {
            this._downArrowSprite.interactive = true;
            this._downArrowSprite.on('mousedown', function(){
                console.log('Right');
                this._clickRightArrow = true;
            })
            this._upArrowSprite.interactive = true;
            this._upArrowSprite.on('mousedown', function(){
                console.log('Left');
                this._clickLeftArrow = true;
            })
            this._addedEvents = true;
        }*/
    };
    
    Window_BookDisplay.prototype.pageIndexText = function() {
        return 'Page    ' + (this._pageIndex + 1).toString() + '/' + (this._pageIndexMax + 1).toString();
    };
    
    // For Compatible with MOG_MenuBackground
    Window_BookDisplay.prototype.needUpdateBackOpacity = function() {
       return false;
    };
    
    Window_BookDisplay.prototype.refreshBook = function() {
        this.contents.clear();
        var book = this._book;
        var cw = this.contentsWidth();
        var ch = this.contentsHeight();
        this.drawHorzLine(34, 3);
        this.drawText(book['Book Title'], 0, 0, cw, 'left');
        
        var txt = this.pageIndexText();
        this.changeTextColor(this.textColor(14));
        this.drawText(txt, 0, 0, cw, 'right');
        this.changeTextColor(this.textColor(0));
        
        var pageText = book.Pages[this._pageIndex]['Text'];
        console.log(pageText);
        this.drawTextEx(pageText, 0, 36);
        this.displayArrows();
    };
    
    Window_BookDisplay.prototype.drawHorzLine = function(y, height) {
        if (height === undefined) height = 1;
        this.contents.fillRect(2, y, this.contentsWidth() - 4, height, this.textColor(0));
    };
    
    Window_BookDisplay.prototype.displayArrows = function() {
        this.downArrowVisible = false;
        this.upArrowVisible = false;
        if (this._pageIndexMax === 0) return;
        if (this._pageIndex === 0 && this._pageIndexMax > 0) this.downArrowVisible = true;
        if (this._pageIndex === this._pageIndexMax && this._pageIndexMax > 0) this.upArrowVisible = true;
        if (this._pageIndex !== 0 && this._pageIndex !== this._pageIndexMax) {
            this.downArrowVisible = true;
            this.upArrowVisible = true;
        }
    }
    
    Window_BookDisplay.prototype._refreshArrows = function() {
        var w = this._width;
        var h = this._height;
        var p = 24;
        var q = p/2;
        var sx = 96+p;
        var sy = 0+p;
        this._downArrowSprite.bitmap = this._windowskin;
        this._downArrowSprite.anchor.x = 0.5;
        this._downArrowSprite.anchor.y = 0.5;
        this._downArrowSprite.setFrame(sx+q+p, sy+q, q, p);
        this._downArrowSprite.move(w - q, h/2);
        this._upArrowSprite.bitmap = this._windowskin;
        this._upArrowSprite.anchor.x = 0.5;
        this._upArrowSprite.anchor.y = 0.5;
        this._upArrowSprite.setFrame(sx, sy+q, q, p);
        this._upArrowSprite.move(q, h/2);
    };
    
    Window_BookDisplay.prototype.hideArrows = function() {
        this.downArrowVisible = false;
        this.upArrowVisible = false;
    };
    
    Window_BookDisplay.prototype.isTouchedInsideFrame = function() {
        var x = this.canvasToLocalX(TouchInput.x);
        var y = this.canvasToLocalY(TouchInput.y);
        return x >= 0 && y >= 0 && x < this.width && y < this.height;
    };
    
    Window_BookDisplay.prototype.updateMouse = function() {
        var x = this.canvasToLocalX(TouchInput.x);
        var y = this.canvasToLocalY(TouchInput.y);
        if (this.downArrowVisible) {
            if (x + 6 >= this._downArrowSprite.x && x + 6 <= this._downArrowSprite.x + 12 &&
                y + 12 >= this._downArrowSprite.y && y + 12 <= this._downArrowSprite.y + 24) {
                    this._clickRightArrow = true;
            }
        }
        if (this.upArrowVisible) {
            if (x + 6 >= this._upArrowSprite.x && x + 6 <= this._upArrowSprite.x + 12 &&
                y + 12 >= this._upArrowSprite.y && y + 12 <= this._upArrowSprite.y + 24) {
                    this._clickLeftArrow = true;
            }
        }
    }
    
    Window_BookDisplay.prototype.updateChangePage = function() {
        if (TouchInput.isTriggered() && this.isTouchedInsideFrame()) {
            this.updateMouse();
        }
        if (Input.isTriggered('right') || this._clickRightArrow) {
            this._pageIndex += 1;
            if (this._pageIndex > this._pageIndexMax) this._pageIndex = 0;
            this.refreshBook();
            AudioManager.playSe(changePageSE);
            this._clickRightArrow = false;
        }
        if (Input.isTriggered('left') || this._clickLeftArrow) {
            this._pageIndex -= 1;
            if (this._pageIndex < 0) this._pageIndex = this._pageIndexMax;
            this.refreshBook();
            AudioManager.playSe(changePageSE);
            this._clickLeftArrow = false;
        }
    };
    
})();