text: //=============================================================================
  // Aloe Guvner - Player Notepad
  // ALOE_PlayerNotepad.js
  //=============================================================================
  
  var Imported = Imported || {};
  Imported.ALOE_PlayerNotepad = true;
  
  var ALOE = ALOE || {};
  ALOE.Alias = ALOE.Alias || {};
  ALOE.PlayerNotepad = {};
  ALOE.PlayerNotepad.version = '1.1.0';
  
  //=============================================================================
  
   /*:
   * @plugindesc v1.2.0 Creates a new scene where players can record notes
   * in a notepad using their keyboard.
   * @author Aloe Guvner
   *
   * @param ---Input Configuration---
   * @default
   * 
   * @param testmode
   * @text Activate Test Mode?
   * @type boolean
   * @default false
   * @on YES
   * @off NO
   * @desc Displays the Key Code in the console every key press.
   * Press F8 to open the console in a playtest.
   * @parent ---Input Configuration---
   * 
   * 
   * @param inputcodes
   * @text Input Codes
   * @type struct<InputCodes>[]
   * @desc Configures the key codes that can be typed.
   * The Key Code is paired with character values.
   * @default ["{\"k\":\"65\",\"c\":\"a\",\"s\":\"A\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"66\",\"c\":\"b\",\"s\":\"B\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"67\",\"c\":\"c\",\"s\":\"C\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"68\",\"c\":\"d\",\"s\":\"D\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"69\",\"c\":\"e\",\"s\":\"E\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"70\",\"c\":\"f\",\"s\":\"F\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"71\",\"c\":\"g\",\"s\":\"G\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"72\",\"c\":\"h\",\"s\":\"H\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"73\",\"c\":\"i\",\"s\":\"I\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"74\",\"c\":\"j\",\"s\":\"J\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"75\",\"c\":\"k\",\"s\":\"K\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"76\",\"c\":\"l\",\"s\":\"L\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"77\",\"c\":\"m\",\"s\":\"M\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"78\",\"c\":\"n\",\"s\":\"N\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"79\",\"c\":\"o\",\"s\":\"O\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"80\",\"c\":\"p\",\"s\":\"P\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"81\",\"c\":\"q\",\"s\":\"Q\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"82\",\"c\":\"r\",\"s\":\"R\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"83\",\"c\":\"s\",\"s\":\"S\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"84\",\"c\":\"t\",\"s\":\"T\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"85\",\"c\":\"u\",\"s\":\"U\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"86\",\"c\":\"v\",\"s\":\"V\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"87\",\"c\":\"w\",\"s\":\"W\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"88\",\"c\":\"x\",\"s\":\"X\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"89\",\"c\":\"y\",\"s\":\"Y\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"90\",\"c\":\"z\",\"s\":\"Z\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"48\",\"c\":\"0\",\"s\":\")\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"49\",\"c\":\"1\",\"s\":\"!\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"50\",\"c\":\"2\",\"s\":\"\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"51\",\"c\":\"3\",\"s\":\"#\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"52\",\"c\":\"4\",\"s\":\"$\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"53\",\"c\":\"5\",\"s\":\"%\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"54\",\"c\":\"6\",\"s\":\"^\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"55\",\"c\":\"7\",\"s\":\"&\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"56\",\"c\":\"8\",\"s\":\"*\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"57\",\"c\":\"9\",\"s\":\"(\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"186\",\"c\":\";\",\"s\":\":\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"187\",\"c\":\"=\",\"s\":\"+\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"188\",\"c\":\",\",\"s\":\"<\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"189\",\"c\":\"-\",\"s\":\"_\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"190\",\"c\":\".\",\"s\":\">\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"191\",\"c\":\"/\",\"s\":\"?\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"192\",\"c\":\"`\",\"s\":\"~\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"219\",\"c\":\"[\",\"s\":\"{\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"220\",\"c\":\"\\\\\",\"s\":\"|\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"221\",\"c\":\"]\",\"s\":\"}\",\"a\":\"\",\"sa\":\"\"}","{\"k\":\"222\",\"c\":\"'\",\"s\":\"\\\"\",\"a\":\"\",\"sa\":\"\"}"]
   * 
   * @param ---Title Settings---
   * @default
   * 
   * @param maxTitleLength
   * @text Max Title Length
   * @type number
   * @parent ---Title Settings---
   * @desc Maximum number of characters for the title.
   * @default 35
   * 
   * @param ---Text Commands---
   * @default
   * 
   * @param newNote
   * @text New Note
   * @type text
   * @parent ---Text Commands---
   * @desc This command appears in the main command window for the player
   * to create a new note.
   * @default New Note
   * 
   * @param saveNote
   * @text Save Note
   * @type text
   * @parent ---Text Commands---
   * @desc This command appears in a window when the player finishes
   * modifying a note. This command will saves changes.
   * @default Save Note
   * 
   * @param discardChanges
   * @text Discard Changes
   * @type text
   * @parent ---Text Commands---
   * @desc This command appears in a window when the player finishes
   * modifying a note. This command discards changes.
   * @default Discard Changes
   * 
   * @param modifyNote
   * @text Modify Note
   * @type text
   * @parent ---Text Commands---
   * @desc This command appears in a window when the player selects a
   * note to modify.
   * @default Modify Note
   * 
   * @param deleteNote
   * @text Delete Note
   * @type text
   * @parent ---Text Commands---
   * @desc This command appears in a window when the player selects a
   * note to delete.
   * @default Delete Note
   * 
   * @param ---Color Settings---
   * @default
   * 
   * @param newNoteColor
   * @text New Note Color
   * @type number
   * @parent ---Color Settings---
   * @min 0
   * @max 31
   * @desc The color ID for the New Note command.
   * Range from 0 - 31 and corresponds to the windowskin color.
   * @default 0
   * 
   * @param saveNoteColor
   * @text Save Note Color
   * @type number
   * @parent ---Color Settings---
   * @min 0
   * @max 31
   * @desc The color ID for the Save Note command.
   * Range from 0 - 31 and corresponds to the windowskin color.
   * @default 0
   * 
   * @param discardChangesColor
   * @text Discard Changes Color
   * @type number
   * @parent ---Color Settings---
   * @min 0
   * @max 31
   * @desc The color ID for the Discard Changes command.
   * Range from 0 - 31 and corresponds to the windowskin color.
   * @default 0
   * 
   * @param modifyNoteColor
   * @text Modify Note Color
   * @type number
   * @parent ---Color Settings---
   * @min 0
   * @max 31
   * @desc The color ID for the Modify Note command.
   * Range from 0 - 31 and corresponds to the windowskin color.
   * @default 0
   * 
   * @param deleteNoteColor
   * @text Delete Note Color
   * @type number
   * @parent ---Color Settings---
   * @min 0
   * @max 31
   * @desc The color ID for the Delete Note command.
   * Range from 0 - 31 and corresponds to the windowskin color.
   * @default 0
   * 
   * @param ---Help Window Instructions---
   * @default 
   * 
   * @param titleInstructions
   * @text Title Instructions
   * @type text
   * @parent ---Help Window Instructions---
   * @desc These instructions appear in the help window when
   * modifying the note title. Use \n for a line break.
   * @default Press ENTER to continue.\nPress ESC to exit without saving.
   * 
   * @param detailsInstructions
   * @text Details Instructions
   * @type text
   * @parent ---Help Window Instructions---
   * @desc These instructions appear in the help window when
   * modifying the note details. Use \n for a line break.
   * @default Press ESC when finished.
   *
   * @param ---Main Menu Integration---
   * @default
   * 
   * @param addToMenu
   * @text Add to main menu?
   * @type boolean
   * @parent ---Main Menu Integration---
   * @desc Controls if the notepad command is added to the main
   * menu. The command is added before the options command.
   * @default true
   * 
   * @param menuCommandName
   * @text Menu Command Name
   * @type text
   * @parent ---Main Menu Integration---
   * @desc The name of the command that will show in the main menu.
   * @default Notepad
   *  
   * @param switchForVisible
   * @text Switch ID# visible
   * @type switch
   * @parent ---Main Menu Integration---
   * @desc Set to the ID# of a Game Switch to toggle if the notepad
   * command is visible in the menu. Leave zero to not use.
   * @default 0
   * 
   * @param switchForEnabled
   * @text Switch ID# enabled
   * @type switch
   * @parent ---Main Menu Integration---
   * @desc Set to the ID# of a Game Switch to toggle if the notepad
   * command is enabled in the menu. Leave zero to not use.
   * @default 0
   * 
   * @param ---Visual Parameters---
   * @default
   * 
   * @param showCursor
   * @text Show Cursor?
   * @type boolean
   * @parent ---Visual Parameters---
   * @desc True/False whether to show the text cursor.
   * @default true
   * 
   * @param cursorBlinkRate
   * @text Cursor Blink Rate
   * @type number
   * @parent ---Visual Parameters---
   * @desc The number of frames for each cursor blink.
   * @default 45
   * 
   * @param cursorOffset
   * @text Cursor Offset
   * @type number
   * @parent ---Visual Parameters---
   * @desc The number of pixels to offset the cursor.
   * Adjust depending on the game's font.
   * @default -5
   * @max 100
   * @min -100
   * 
   * @param fadeLockedText
   * @text Fade Locked Text?
   * @type boolean
   * @parent ---Visual Parameters---
   * @desc Fades the text of the title and/or details
   * if it is locked from modifying.
   * @default true
   * 
   * @param startingNotes
   * @text Starting Notes
   * @type struct<StartingNotes>[]
   * @desc Notes can be defined in this parameter that will be
   * automatically added in a new game.
   * 
   * @help
   * ============================================================================
   * Introduction
   * ============================================================================
   *
   * This plugin creates a new scene where the player can create, modify, and delete
   * notes.
   *
   * ============================================================================
   * Plugin Configuration
   * ============================================================================
   * 
   * This plugin is configured by default for a standard English QWERTY keyboard.
   * The parameter that controls the input contains:
   *  1. The unique Key Code of the key (for example, 'a' is 65)
   *  2. The character to type when the Key Code is pressed
   *  3. The character to type when the Key Code is pressed and Shift is pressed.
   *  4. The character to type when the Key Code is pressed and Alt is pressed.
   *  5. The character to type when the Key Code is pressed and Shift + Alt 
   *     is pressed.
   * 
   * 
   * If the English QWERTY keyboard is used, no changes are required except to
   * add the (at) symbol for the 'shifted' version of the number 2. The reason is
   * that the editor does not allow the (at) symbol to be in the default values of
   * parameters. In fact, the (at) symbol cannot even be used in the help section.
   * 
   * For keyboards that do not follow the English QWERTY format (such as 
   * AZERTY or QWERTZ keyboards), the plugin parameter can be changed to match
   * those keyboards.
   * A test mode is included to identify the proper Key Code for each key.
   * Enable the test mode through the plugin parameter and open the console
   * in a playtest by pressing F8. Each Key Code will be displayed there when
   * the key is pressed.
   * 
   * ============================================================================
   * Instructions
   * ============================================================================
   *
   * The notepad may be opened by plugin command, script call, or main menu. 
   * The script call can be used in another plugin or in an event, and the plugin
   * command can be used within an event.
   * 
   * The script call to open the notepad scene is:
   * SceneManager.push(Scene_Notepad);
   * 
   * The plugin call is described in its own section below.
   * 
   * This plugin includes native integration with the main menu to add a notepad
   * command to open the notepad scene. Plugin parameters exist to allow the 
   * developer to customize or disable this functionality.
   * 
   * To integrate this plugin with the Yanfly Main Menu Manager, be sure to disable
   * the included main menu integration from this plugin's parameters. In the 
   * Yanfly plugin use the following example parameters.
   * 
   * Menu X Name:
   * Notepad   (suggestion)
   *
   * Menu X Symbol:
   * notepad   (suggestion)
   *
   * Menu X Main Bind:
   * this.commandNotepad.bind(this)
   * 
   *
   * ============================================================================
   * Plugin Commands
   * ============================================================================
   * 
   * The plugin commands available in this plugin are described below. The syntax
   * for the commands is preceded by the <> symbols. These symbols are only for
   * formatting purposes and are not actually part of the plugin commands.
   * Plugin commands are not case-sensitive.
   * 
   * =====Open Notepad Scene=====
   * 
   * The following plugin command will open the notepad scene:
   *    <>notepad open
   * 
   * =====Staging Note Data for Adding and Modifying=====
   * 
   * The following plugin commands can be used in combination to add or modify
   * notes. The staged data will be processed when the 'add' or 'modify' plugin
   * commands are used.
   * 
   * To stage the title for adding/modifying, use the following plugin command.
   * The title is a mandatory field for adding a new note.
   *    <>notepad stage title [title]
   * 
   * To stage the details for adding/modifying, use the following plugin command.
   * Line breaks can be added by using the \n character.
   *    <>notepad stage details [details]
   * 
   * To stage the key for adding/modifying, use the following plugin command.
   * The key is a mandatory field if you need to modify/delete the note later.
   *    <>notepad stage key [key]
   * 
   * To set the note to be locked (both title and details not modifiable), use
   * the following plugin command. The default value is false; it is not 
   * necessary to use this plugin command unless the desired value is true.
   *    <>notepad stage bothlocked [boolean]
   * 
   * To set the note title to be locked use the following plugin command. 
   * The default value is false; it is not necessary to use this plugin command
   * unless the desired value is true.
   *    <>notepad stage titlelocked [boolean]
   * 
   * To set the note details to be locked use the following plugin command. 
   * The default value is false; it is not necessary to use this plugin command
   * unless the desired value is true.
   *    <>notepad stage detailslocked [boolean]
   * 
   * To add/modify the note, use the following plugin command. If the key does
   * not already exist, or the key is left blank, then a new note is added.
   * If the key already exists, then the existing note that matches that key
   * is modified.
   * 
   *    <>notepad stage add
   * 
   * To modify the note by appending text to the title or details, use the
   * following plugin command. For this command, the key must exist otherwise
   * nothing will happen.
   * 
   *    <>notepad stage append
   * 
   * 
   * Example Add.
   * The following example plugin commands creates a new note with a key of "alchemy", title and
   * details as below, and with the title locked from modifying.
   * 
   *    <>notepad stage title Alchemy Recipes
   *    <>notepad stage details -Potion + Stimulant = Super Potion\nHerb + Poison Fang = Antidote
   *    <>notepad stage key alchemy
   *    <>notepad stage titlelocked true
   *    <>notepad stage add
   * 
   * Example Modify.
   * The following example plugin commands will locate an already existing note with a key of
   * "password", replace the details with "Blue Door: 33121", and lock the details from modifying.
   * 
   *    <>notepad stage details Blue Door: 33121
   *    <>notepad stage key password
   *    <>notepad stage detailslocked true
   *    <>notepad stage add
   * 
   * Example Append.
   * The following example plugin commands will locate an already existing note with a key of
   * "crime_clues", and append the details with "Fingerprint found on the handle"
   * 
   *    <>notepad stage details Fingerprint found on the handle
   *    <>notepad stage key crime_clues
   *    <>notepad stage append
   * 
   * =====Locking Individual Notes=====
   * 
   * The following plugin command will lock an existing note from modifying the
   * title of the given [key].
   * 
   *    <>notepad lock title [key]
   * 
   * The following plugin command will lock an existing note from modifying the 
   * details of the given [key].
   * 
   *    <>notepad lock details [key]
   * 
   * The following plugin command will lock an existing note from modifying both 
   * title and details of the given [key].
   * 
   *    <>notepad lock both [key]
   * 
   * The following plugin command will lock an existing note from being deleted.
   * 
   *    <>notepad lock delete [key]
   * 
   * Examples:
   *    <>notepad lock title alchemy
   *    <>notepad lock details crimenotes
   *    <>notepad lock both puzzlesolutions
   *    <>notepad lock delete instructions
   * 
   * =====Unlocking Individual Notes=====
   * 
   * The following plugin command will unlock an existing note for modifying 
   * the title of the given [key].
   * 
   *    <>notepad unlock title [key]
   * 
   * The following plugin command will unlock an existing note for modifying 
   * the details of the given [key].
   * 
   *    <>notepad unlock details [key]
   * 
   * The following plugin command will unlock an existing note for modifying
   * both title and details of the given [key].
   * 
   *    <>notepad unlock both [key]
   * 
   * The following plugin command will unlock an existing note for deleting.
   * 
   *    <>notepad unlock delete [key]
   * 
   * Examples:
   *    <>notepad unlock title alchemy
   *    <>notepad unlock details crimenotes
   *    <>notepad unlock both puzzlesolutions
   *    <>notepad unlock delete instructions
   * 
   * =====Deleting Notes (Individual and Collective)=====
   * 
   * The following plugin command will delete an existing note. The [key] to uniquely
   * identify the note must be specified:
   *    <>notepad delete key [key]
   * 
   * The following plugin command will delete all existing notes:
   *    <>notepad delete all
   * 
   * =====Disabling Features=====
   * 
   * The following plugin command will disable the player from adding new notes:
   *    <>notepad disable new
   * 
   * The following plugin command will disable the player from modifying notes:
   *    <>notepad disable modify
   * 
   * The following plugin command will disable the player from deleting notes:
   *    <>notepad disable delete
   * 
   * 
   * =====Enabling Features=====
   * 
   * The following plugin command will enable the player from adding new notes:
   *    <>notepad enable new
   * 
   * The following plugin command will enable the player from modifying notes:
   *    <>notepad enable modify
   * 
   * The following plugin command will enable the player from deleting notes:
   *    <>notepad enable delete
   * 
   * =====Hide / Show Notes=====
   * 
   * The following plugin command will hide a note from the player.
   * The note is not deleted, it is simply hidden from the player's view.
   * 
   *    <>notepad hide [key]
   * 
   * The following plugin command will show a note to the player.
   * This will reveal a note that was previously hidden.
   * 
   *    <>notepad show [key]
   * 
   * =====Searching in Notes=====
   * 
   * The following plugin commands allow the developer to search through
   * existing notes for a specific string. The search is not case sensitive,
   * so any result (upper or lower case) that matches is returned.
   * 
   *    <>notepad search [v] titles for [string]
   *    <>notepad search [v] key [key] for [string]
   *    <>notepad search [v] details for [string]
   * 
   * [v] --> Game Variable ID to store the string in, if found.
   * If not found, this will be set to an empty string. This can also be used for
   * a true/false test, because an empty string is a falsy value.
   * 
   * [string] --> What you would like to search for.
   * 
   * [key] --> Unique key of a note, if you want to search a specific note.
   * 
   * Examples:
   *    <>notepad search 19 titles for Once upon a time...
   *    <>notepad search 20 key recipes for Super Potion
   *    <>notepad search 18 details for Shaken, not Stirred.
   * 
   * $gameVariables.value(19) will contain the string "Once upon a time..." if found.
   * $gameVariables.value(20) will contain the string "Super Potion" if found.
   * $gameVariables.value(18) will contain the string "Shaken, not Stirred" if found.
   * 
   * If any of these strings are not found, the value in the game variable is set to 0.
   * 
   * ============================================================================
   * Script Calls
   * ============================================================================
   * 
   * $gameNotepad.deleteNoteByKey(key)
   * -- Deletes a note with the given key.
   * --- key: unique key of the note
   * 
   * $gameNotepad.deleteAllNotes()
   * -- Deletes all notes
   * 
   * $gameNotepad.modifyNoteByKey(key, title, details, titleLocked, detailsLocked, deleteLocked, hidden)
   * -- Modifies a note with the given key
   * --- key: unique key of the note
   * --- title: title of the note
   * --- details: details of the note
   * --- titleLocked: whether the title is locked from being edited
   * --- detailsLocked: whether the details are locked from being edited
   * --- deleteLocked: whether the note is locked from being deleted
   * --- hidden: whether the note is hidden in the notepad
   * 
   * $gameNotepad.appendNoteByKey(key, title, details)
   * -- Appends to a note with the given key
   * --- key: unique key of the note
   * --- title: text to append to the existing title
   * --- details: details to append to the existing details
   * 
   * $gameNotepad.addNote(title, details, key, titleLocked, detailsLocked, deleteLocked, hidden)
   * -- Adds a new note to the notepad
   * --- title: title of the note
   * --- details: details of the note
   * --- key: unique key of the note
   * --- titleLocked: whether the title is locked from being edited
   * --- detailsLocked: whether the details are locked from being edited
   * --- deleteLocked: whether the note is locked from being deleted
   * --- hidden: whether the note is hidden in the notepad
   * 
   * $gameNotepad.lockTitle(key)
   * -- Locks the title of a note with the given key
   * --- key: unique key of the note
   * 
   * $gameNotepad.lockDetails(key)
   * -- Locks the details of a note with the given key
   * --- key: unique key of the note
   * 
   * $gameNotepad.lockDelete(key)
   * -- Locks a note with the given key from being deleted
   * --- key: unique key of the note
   * 
   * $gameNotepad.unlockTitle(key)
   * -- Unlocks the title of a note with the given key
   * --- key: unique key of the note
   * 
   * $gameNotepad.unlockDetails(key)
   * -- Unlocks the details of a note with the given key
   * --- key: unique key of the note
   * 
   * $gameNotepad.unlockDelete(key)
   * -- Unlocks a note with the given key from being deleted
   * --- key: unique key of the note
   * 
   * $gameNotepad.hide(key)
   * -- Hides a note with the given key
   * --- key: unique key of the note
   * 
   * $gameNotepad.show(key)
   * -- Unhides a note with the given key
   * ---key: unique key of the note
   * 
   * $gameNotepad.disableFeature(feature)
   * -- Disables the given feature of the notepad
   * --- feature: new, modify, or delete
   * 
   * $gameNotepad.enableFeature(feature)
   * -- Enables the given feature of the notepad
   * --- feature: new, modify, or delete
   * 
   * $gameNotepad.searchTitles(term, variableId)
   * -- Searches through the notes for a title containing the term
   * --- term: the term/words/characters to look for
   * --- variableId: the title is saved to this variable if found
   * 
   * $gameNotepad.searchDetails(term, variableId)
   * -- Searches through the notes for a details containing the term
   * --- term: the term/words/characters to look for
   * --- variableId: the title is saved to this variable if found
   * 
   * $gameNotepad.searchKey(key, term, variableId)
   * -- Searches through a specific note to see if it contains the term
   * --- key: the unique key of the note to search
   * --- term: the term/words/characters to look for
   * --- variableId: the title/details is saved to this variable if found
   * 
   * 
   * ============================================================================
   * Changelog
   * ============================================================================
   * Version 1.2.0:
   * - Add plugin command and function to append to notes rather than replacing
   *   their contents.
   * - Fix the help section so all of it shows in the Plugin Manager.
   * Version 1.1.0:
   * - Change version schema to Semantic Versioning
   * - Add ability to configure "alt" characters for additional flexibility
   *   for non-English keyboards.
   * Version 1.02:
   * - Characters to type are now configurable in the plugin parameters and
   *   are no longer hard-coded to an English QWERTY keyboard.
   * Version 1.01:
   * - Fixed a bug where the cursor was not in the correct position for certain
   *   fonts.
   * - Added a parameter to offset the cursor, can be used to adjust the cursor
   *   to look good with any font.
   * - Added proper scrolling to the left/right keys at the beginning/end of the
   *   lines.
   * - Modulated/cleaned code in various methods.
   * Version 1.00:
   * - Initial release
   */
  
    /*~struct~StartingNotes:
   * @param title
   * @text Title
   * @type text
   * @desc Title of the note.
   * 
   * @param details
   * @text Details
   * @type note
   * @desc Details of the note.
   * 
   * @param key
   * @text Key
   * @type text
   * @desc Key of the note.
   * The key is a single word that uniquely identifies a note.
   * 
   * @param titleLocked
   * @text Title Locked?
   * @type boolean
   * @desc Determines whether the title of this note is locked by default.
   * Locked means that it cannot be modified.
   * @default false
   * 
   * @param detailsLocked
   * @text Details Locked?
   * @type boolean
   * @desc Determines whether the details of this note are locked by default.
   * Locked means that it cannot be modified.
   * @default false
   * 
   * @param deleteLocked
   * @text Delete Locked
   * @type boolean
   * @desc Determines whether the note is locked from being deleted.
   * Locked means that it cannot be deleted.
   * @default false
   * 
   * @param hidden
   * @text Hidden
   * @type boolean
   * @desc Determines whether the note is hidden at the start.
   * Hidden means it is not shown to the player.
   * @default false
   */
  
    /*~struct~InputCodes:
   * @param k
   * @text Key Code
   * @type text
   * @desc Unique code corresponding to the key press.
   * Sometimes known as the ASCII key code.
   * 
   * @param c
   * @text Character
   * @type text
   * @desc The text to draw if the Key Code is pressed.
   * 
   * @param s
   * @text Shifted character
   * @type text
   * @desc The text to draw if the Key Code is pressed while SHIFT
   * is pressed
   * 
   * @param a
   * @text Alted character
   * @type text
   * @desc The text to draw if the Key Code is pressed while
   * ALT is pressed
   * 
   * @param sa
   * @text Shifted Alted Character
   * @type text
   * @desc The text to draw if the Key Code is pressed while
   * SHIFT and ALT are pressed
   * 
   */
  
  //=============================================================================
  
  //=============================================================================
  // Utility Functions
  //
  //=============================================================================
  // recursiveParse:
  // Due to the way that the editor stringifies object/array parameters, 
  // JSON.parse must be called recursively on these parameters.
  //=============================================================================
  
  //Syntax & inspiration from DK Plugins & SRD
  //The editor does not stringify complex parameters in JSON format.
  //Instead, it stringifies it in layers. This means that we have to
  //parse it recursively.
  
  ALOE.recursiveParse = function(param) {
      try {
          return JSON.parse(param, function(key, value) {
              try {
                  //if it can still be parsed, keep going
                  return this.recursiveParse(value);
              } catch (e) {
                  //when it can't be parsed anymore, return it
                  return value;
              }
          }.bind(this));
      } catch (e) { //non bool/num strings error immediately so return
          return param;
      }
  };
  
  //=============================================================================
  // Parameters
  //=============================================================================
  // Grab all parameters from the Plugin Manager and parse to automatically
  // convert data types (i.e. "true" --> true ; "12" --> 12)
  //=============================================================================
  
  ALOE.PlayerNotepad.params = {};
  (function() {
      var params = PluginManager.parameters("ALOE_PlayerNotepad");
      var keys = Object.keys(params);
      var length = keys.length;
      for (var i = 0; i < length; i++) {
          ALOE.PlayerNotepad.params[keys[i]] = ALOE.recursiveParse(params[keys[i]]);
      }
  })();
  
  if(ALOE.PlayerNotepad.params.startingNotes) {
      ALOE.PlayerNotepad.params.startingNotes.forEach(function(a){
          a.title = [a.title]; 
          a.details = a.details.split("\n");
      });
  }
  
  //=============================================================================
  // Data Setup
  //=============================================================================
  // Define the global variable and alias the DataManager methods for creating,
  // saving, and loading game objects.
  //=============================================================================
  
  let $gameNotepad = null;
  
  ALOE.Alias.DataManager_createGameObjects = DataManager.createGameObjects;
  DataManager.createGameObjects = function() {
      ALOE.Alias.DataManager_createGameObjects.call(this);
      $gameNotepad = new Game_Notepad();
      if(ALOE.PlayerNotepad.params.startingNotes) {
          ALOE.PlayerNotepad.params.startingNotes.forEach(function(a){
                  a.id = $gameNotepad.nextId();
                  $gameNotepad._data.push(a);
          });
      }
  };
  
  ALOE.Alias.DataManager_makeSaveContents = DataManager.makeSaveContents;
  DataManager.makeSaveContents = function() {
      var contents = ALOE.Alias.DataManager_makeSaveContents.call(this);
      contents.gameNotepad = $gameNotepad;
      return contents;
  };
  
  ALOE.Alias.DataManager_extractSaveContents = DataManager.extractSaveContents;
  DataManager.extractSaveContents = function(contents){
      ALOE.Alias.DataManager_extractSaveContents.call(this, contents);
      if (contents.gameNotepad) {$gameNotepad = contents.gameNotepad;}
  };
  
  //=============================================================================
  // Game_Notepad
  //=============================================================================
  // Define a new class for the notepad and the methods of the prototype.
  //=============================================================================
  
  function Game_Notepad() {
      this._data = [];
      this._stage = {title: [""], details: [""], key: "", 
              titleLocked: false, detailsLocked: false,
              deleteLocked: false, hidden: false};
      this._features = {new: true, modify: true, delete: true};
  }
  
  Game_Notepad.prototype.note = function(index) {
      return this._data[index];
  };
  
  Game_Notepad.prototype.titleById = function(id) {
      for(var i = 0; i < this.allNotes().length; i++) {
          if(this.allNotes()[i].id == id) {
              return this.allNotes()[i].title;
          }
      }
      return [""];
  };
  
  Game_Notepad.prototype.detailsById = function(id) {
      for(var i = 0; i < this.allNotes().length; i++) {
          if(this.allNotes()[i].id == id) {
              return this.allNotes()[i].details;
          }
      }
      return [""];
  };
  
  Game_Notepad.prototype.allNotes = function() {
      return this._data.filter(function(a) {return a;});
  };
  
  Game_Notepad.prototype.nextId = function() {
      if(this._data.length) {
          return this._data[this._data.length - 1].id + 1;
      }
      return 1;
  };
  
  Game_Notepad.prototype.keyExists = function(key) {
      return this.allNotes().map(function(a){return a.key;}).indexOf(key) >= 0;
  };
  
  Game_Notepad.prototype.getIdByKey = function(key) {
      var index =  this.allNotes().map(function(a){return a.key;}).indexOf(key);
      return this.note(index).id;
  };
  
  Game_Notepad.prototype.addNote = function(title, details, key, titleLocked,
       detailsLocked, deleteLocked, hidden) {
      title = title || [""];
      details = details || [""];
      key = key || "";
      titleLocked = titleLocked || false;
      detailsLocked = detailsLocked || false;
      deleteLocked = deleteLocked || false;
      hidden = hidden || false;
      this._data.push({id: this.nextId(), title: title, details: details, key: key, hidden: hidden,
          titleLocked: titleLocked, detailsLocked: detailsLocked, deleteLocked: deleteLocked});
  };
  
  Game_Notepad.prototype.modifyNoteById = function(id, title, details) {
      var index = this.allNotes().map(function(a){return a.id;}).indexOf(id);
      this._data[index].title = title || this.titleById(id);
      this._data[index].details = details || this.detailsById(id);
  };
  
  Game_Notepad.prototype.modifyNoteByKey = function(key, title, details, titleLocked,
       detailsLocked, deleteLocked, hidden) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      this._data[index].title = title || this.titleById(id);
      this._data[index].details = details !== undefined ? details : this.detailsById(id);
      this._data[index].titleLocked = titleLocked !== undefined ? titleLocked : this._data[index].titleLocked;
      this._data[index].detailsLocked = detailsLocked !== undefined ? detailsLocked : this._data[index].detailsLocked;
      this._data[index].deleteLocked = deleteLocked !== undefined ? deleteLocked : this._data[index].deleteLocked;
      this._data[index].hidden = hidden !== undefined ? hidden : this._data[index].hidden;
  };
  
  Game_Notepad.prototype.appendNoteByKey = function(key, title, details) {
      var index = this.allNotes().map(function(note){return note.key;}).indexOf(key);
      if (title) {this._data[index].title[0] += title;}
      if (details) {this._data[index].details = this._data[index].details.concat(details);}
  };
  
  Game_Notepad.prototype.deleteNoteById = function(id) {
      id = parseInt(id);
      var index = this.allNotes().map(function(a){return a.id;}).indexOf(id);
      this._data.splice(index, 1);
  };
  
  Game_Notepad.prototype.deleteNoteByKey = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this._data.splice(index, 1);
      }
  };
  
  Game_Notepad.prototype.deleteAllNotes = function() {
      this._data = [];
  };
  
  Game_Notepad.prototype.lockTitle = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this.note(index).titleLocked = true;
      }
  };
  
  Game_Notepad.prototype.unlockTitle = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this.note(index).titleLocked = false;
      }
  };
  
  Game_Notepad.prototype.lockDetails = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this.note(index).detailsLocked = true;
      }
  };
  
  Game_Notepad.prototype.unlockDetails = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this.note(index).detailsLocked = false;
      }
  };
  
  Game_Notepad.prototype.lockDelete = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this.note(index).deleteLocked = true;
      }
  };
  
  Game_Notepad.prototype.unlockDelete = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this.note(index).deleteLocked = false;
      }
  };
  
  Game_Notepad.prototype.enableFeature = function(feature) {
      this._features[feature] = true;
  };
  
  Game_Notepad.prototype.disableFeature = function(feature) {
      this._features[feature] = false;
  };
  
  Game_Notepad.prototype.setStage = function(type, value) {
      switch (type.toLowerCase()) {
          case "title":
              this._stage.title = value;
              break;
          case "details":
              this._stage.details = value;
              break;
          case "key":
              this._stage.key = value;
              break;
          case "titlelocked":
              this._stage.titleLocked = value;
              break;
          case "detailslocked":
              this._stage.detailsLocked = value;
              break;
          case "deletelocked":
              this._stage.deleteLocked = value;
              break;
          case "hidden":
              this._stage.hidden = value;
              break;
          default:
              break;
      }
  };
  
  Game_Notepad.prototype.getStage = function(type) {
      switch (type.toLowerCase()) {
          case "title":
              return this._stage.title;
          case "details":
              return this._stage.details;
          case "key":
              return this._stage.key;
          case "titlelocked":
              return this._stage.titleLocked;
          case "detailslocked":
              return this._stage.detailsLocked;
          case "deletelocked":
              return this._stage.deleteLocked;
          case "hidden":
              return this._stage.hidden;
          default:
              break;
      }
  };
  
  Game_Notepad.prototype.clearStage = function() {
      this._stage = {title: [""], details: [""], key: "", 
      titleLocked: false, detailsLocked: false, deleteLocked: false, hidden: false};
  };
  
  Game_Notepad.prototype.searchTitles = function(term, variableId) {
      var regExp = new RegExp(term, "i");
      var title = "";
      var match;
      for (var i = 0; i < $gameNotepad.allNotes().length; i++) {
          title = $gameNotepad.allNotes()[i].title[0];
          match = title.match(regExp);
          if(match) {
              break;
          }
      }
      if(match) {
          $gameVariables.setValue(variableId, match[0]);
      } else {
          $gameVariables.setValue(variableId, 0);
      }
  };
  
  Game_Notepad.prototype.searchKey = function(key, term, variableId) {
      var regExp = new RegExp(term, "i");
      var id = $gameNotepad.getIdByKey(key);
      var title = $gameNotepad.titleById(id)[0];
      var match = title.match(regExp);
      if(match) {
          $gameVariables.setValue(variableId, match[0]);
      } else {
          var details = $gameNotepad.detailsById(id).join("");
          match = details.match(regExp);
          if(match) {
              $gameVariables.setValue(variableId, match[0]);
          } else {
              $gameVariables.setValue(variableId, 0);
          }
      }
  };
  
  Game_Notepad.prototype.searchDetails = function(term, variableId) {
      var regExp = new RegExp(term, "i");
      var details = "";
      var match;
      for (var i = 0; i < $gameNotepad.allNotes().length; i++) {
          details = $gameNotepad.allNotes()[i].details.join("");
          match = details.match(regExp);
          if(match) {
              break;
          }
      }
      if(match) {
          $gameVariables.setValue(variableId, match[0]);
      } else {
          $gameVariables.setValue(variableId, 0);
      }
  };
  
  Game_Notepad.prototype.hide = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this.note(index).hidden = true;
      }
  };
  
  Game_Notepad.prototype.show = function(key) {
      var index = this.allNotes().map(function(a){return a.key;}).indexOf(key);
      if (index >= 0) {
          this.note(index).hidden = false;
      }
  };
  
  Game_Notepad.prototype.newEnabled = function() {
      return this._features.new;
  };
  
  Game_Notepad.prototype.modifyEnabled = function() {
      return this._features.modify;
  };
  
  Game_Notepad.prototype.deleteEnabled = function() {
      return this._features.delete;
  };
  
  Game_Notepad.prototype.isNoteDeletable = function(id) {
      if(this.deleteEnabled()) {
          var index = this.allNotes().map(function(a){return a.id;}).indexOf(id);
          return !this.note(index).deleteLocked;
      }
      return false;
  };
  
  Game_Notepad.prototype.isNoteModifiable = function(id) {
      if(this.modifyEnabled()) {
          var index = this.allNotes().map(function(a){return a.id;}).indexOf(id);
          return !this.note(index).titleLocked || !this.note(index).detailsLocked;
      }
      return false;
  };
  
  Game_Notepad.prototype.isNoteTitleModifiable = function(id) {
      var index = this.allNotes().map(function(a){return a.id;}).indexOf(id);
      if (index >= 0) {return !this.note(index).titleLocked;}
  };
  
  Game_Notepad.prototype.isNoteDetailsModifiable = function(id) {
      var index = this.allNotes().map(function(a){return a.id;}).indexOf(id);
      if (index >= 0) {return !this.note(index).detailsLocked;}
  };
  
  //=============================================================================
  // Scene_Notepad
  //=============================================================================
  // New class to run the notepad scene. Functions include:
  // -Window creation
  // -Window handlers
  // -Input mapping
  // -Input processing
  //=============================================================================
  
  function Scene_Notepad() {
      this.initialize.apply(this, arguments);
  }
  
  Scene_Notepad.prototype = Object.create(Scene_MenuBase.prototype);
  Scene_Notepad.prototype.constructor = Scene_Notepad;
  
  Scene_Notepad.prototype.initialize = function() {
      Scene_MenuBase.prototype.initialize.call(this);
      this.storeOriginalInputMapper();
      this._isShifted = false;
      this._isAlted = false;
      this._frameCounter = 0;
      this._blinkRate = ALOE.PlayerNotepad.params.cursorBlinkRate;
      this._tempTitle = [];
      this._tempDetails = [];
  };
  
  Scene_Notepad.prototype.create = function() {
      Scene_MenuBase.prototype.create.call(this);
      this.createCommandWindow();
      this.createHelpWindow();
      this.createTitleWindow();
      this.createDetailsWindow();
      this._commandWindow.updateNotesWindows();
      this.createConfirmCommandWindow();
      this.createExistingNoteCommandWindow();
      this.setStandardHandlers();
      this.setNoteHandlers();
  };
  
  Scene_Notepad.prototype.start = function() {
      Scene_MenuBase.prototype.start.call(this);
  };
  
  Scene_Notepad.prototype.createCommandWindow = function() {
      this._commandWindow = new Window_NotepadCommand(0, 0);
      this.addWindow(this._commandWindow);
  };
  
  Scene_Notepad.prototype.setStandardHandlers = function() {
      this._commandWindow.setHandler('cancel',          this.popScene.bind(this));
      this._commandWindow.setHandler('newnote',         this.commandNewNote.bind(this));
      this._confirmCommandWindow.setHandler('save',     this.commandSaveNote.bind(this));
      this._confirmCommandWindow.setHandler('discard',  this.commandDiscardNote.bind(this));
      this._confirmCommandWindow.setHandler('cancel',   this.commandDiscardNote.bind(this));
      this._existingCommandWindow.setHandler('modify',    this.commandModifyNote.bind(this));
      this._existingCommandWindow.setHandler('delete',  this.commandDeleteNote.bind(this));
      this._existingCommandWindow.setHandler('cancel',  this.commandCancelExisting.bind(this));
  };
  
  Scene_Notepad.prototype.setNoteHandlers = function() {
      var allNotes = $gameNotepad.allNotes();
      for (var i = 0; i < allNotes.length; i++) {
          this._commandWindow.setHandler('id'+allNotes[i].id, this.commandExistingNote.bind(this));
      }
  };
  
  Scene_Notepad.prototype.createHelpWindow = function() {
      var x = this._commandWindow.width;
      var width = Graphics.width - this._commandWindow.width;
      this._helpWindow = new Window_NotepadHelp(x, width);
      this.addWindow(this._helpWindow);
  };
  
  Scene_Notepad.prototype.createTitleWindow = function() {
      var x = this._commandWindow.width;
      var y = 0;
      var width = Graphics.width - this._commandWindow.width;
      var height = Graphics.height / 8;
      this._titleWindow = new Window_NotepadTitle(x, y, width, height);
      this.addWindow(this._titleWindow);
      this._commandWindow._subTitleWindow = this._titleWindow;
  };
  
  Scene_Notepad.prototype.createDetailsWindow = function() {
      var x = this._commandWindow.width;
      var y = this._titleWindow.height;
      var width = Graphics.width - this._commandWindow.width;
      var height = Graphics.height - this._titleWindow.height - this._helpWindow.height;
      this._detailsWindow = new Window_NotepadDetails(x, y, width, height);
      this.addWindow(this._detailsWindow);
      this._commandWindow._subDetailsWindow = this._detailsWindow;
  };
  
  Scene_Notepad.prototype.createConfirmCommandWindow = function() {
      var x = 100; //hardcoded
      var y = 100; //hardcoded
      this._confirmCommandWindow = new Window_ConfirmChangesCommand(x, y);
      this._confirmCommandWindow.hide();
      this._confirmCommandWindow.deactivate();
      this.addWindow(this._confirmCommandWindow);
  };
  
  Scene_Notepad.prototype.createExistingNoteCommandWindow = function() {
      var x = 0;
      var y = 0;
      this._existingCommandWindow = new Window_ExistingNoteCommand(x, y);
      this._existingCommandWindow.hide();
      this._existingCommandWindow.deactivate();
      this.addWindow(this._existingCommandWindow);
  };
  
  Scene_Notepad.prototype.commandNewNote = function() {
      this.createMyInputMapper();
      this._commandWindow._lastCommandSymbol = this._commandWindow.currentSymbol();
      this._commandWindow.deselect();
      this._activeWindow = this._titleWindow;
      this._titleWindow.activate();
      this._titleWindow.refresh();
      this._helpWindow.setTitleText();
  };
  
  Scene_Notepad.prototype.commandExistingNote = function() {
      this._commandWindow._lastCommandSymbol = this._commandWindow.currentSymbol();
      this._commandWindow.deselect();
      this._existingCommandWindow.show();
      this._existingCommandWindow.activate();
      this._existingCommandWindow.refresh();
      this._existingCommandWindow.selectSymbol(this._existingCommandWindow._lastCommandSymbol);
  };
  
  Scene_Notepad.prototype.commandSaveNote = function() {
      var id = parseInt(this._commandWindow._lastCommandSymbol.slice(2));
      var index = $gameNotepad.allNotes().map(function(a){return a.id;}).indexOf(id);
      if (index < 0) {
          $gameNotepad.addNote(this._titleWindow.text, this._detailsWindow.text);
      }
      this._titleWindow.clear();
      this._detailsWindow.clear();
      this._confirmCommandWindow.deselect();
      this._confirmCommandWindow.hide();
      this._commandWindow.refresh();
      this._commandWindow.activate();
      this._commandWindow.selectLast();
      this._activeWindow = null;
      this.resetInputMapper();
      this.setNoteHandlers();
  };
  
  Scene_Notepad.prototype.commandDiscardNote = function() {
      //Reset the $gameNotepad data
      var id = parseInt(this._commandWindow._lastCommandSymbol.slice(2));
      if (id) {
          $gameNotepad.modifyNoteById(id, this._tempTitle, this._tempDetails);
      }
      //Show/activate the appropriate windows
      this._titleWindow.clear();
      this._detailsWindow.clear();
      this._confirmCommandWindow.deselect();
      this._confirmCommandWindow.hide();
      this._commandWindow.refresh();
      this._commandWindow.activate();
      this._commandWindow.selectLast();
      this._activeWindow = null;
      //Reset command window handlers
      this.setNoteHandlers();
  };
  
  Scene_Notepad.prototype.commandModifyNote = function() {
      this.createMyInputMapper();
      var id = parseInt(this._commandWindow._lastCommandSymbol.slice(2));
      this._tempTitle = $gameNotepad.titleById(id).slice();
      this._tempDetails = $gameNotepad.detailsById(id).slice();
      this._commandWindow.deselect();
      this._existingCommandWindow._lastCommandSymbol = this._existingCommandWindow.currentSymbol();
      this._existingCommandWindow.deselect();
      this._existingCommandWindow.hide();
      if ($gameNotepad.isNoteTitleModifiable(id)) {
          this._activeWindow = this._titleWindow;
          this._titleWindow.activate();
          this._titleWindow.refresh();
          this._helpWindow.setTitleText();
      } else {
          this._activeWindow = this._detailsWindow;
          this._detailsWindow.activate();
          this._detailsWindow.refresh();
          this._helpWindow.setDetailsText();
      }
  };
  
  Scene_Notepad.prototype.commandDeleteNote = function() {
      var id = parseInt(this._commandWindow._lastCommandSymbol.slice(2));
      $gameNotepad.deleteNoteById(id);
      this._commandWindow.removeCommand(this._commandWindow._lastCommandSymbol);
      this._existingCommandWindow.deselect();
      this._existingCommandWindow.hide();
      this._commandWindow.refresh();
      this._commandWindow.activate();
      this._commandWindow.select(0);
      this._titleWindow.clear();
      this._detailsWindow.clear();
  };
  
  Scene_Notepad.prototype.commandCancelExisting = function() {
      this._existingCommandWindow.deselect();
      this._existingCommandWindow.hide();
      this._commandWindow.activate();
      this._commandWindow.selectLast();
      SoundManager.playCancel();
  };
  
  Scene_Notepad.prototype.popScene = function() {
      this.resetInputMapper();
      Scene_Base.prototype.popScene.call(this);
  };
  
  Scene_Notepad.prototype.storeOriginalInputMapper = function() {
      this._originalInputKeyMapper = JSON.parse(JSON.stringify(Input.keyMapper));
  };
  
  Scene_Notepad.prototype.resetInputMapper = function() {
      Input.keyMapper = JSON.parse(JSON.stringify(this._originalInputKeyMapper));
  };
  
  Scene_Notepad.prototype.createMyInputMapper = function() {
      Input.keyMapper = {};
      Input.shiftedKeyMapper = {};
      ALOE.PlayerNotepad.params.inputcodes.forEach(function(a){
          if(typeof(a.c) === "string") {
              Input.keyMapper[a.k] = a.c;
          } else if (typeof(a.c) === "number") {
              Input.keyMapper[a.k] = '.' + a.c; 
              //Input class doesn't like pure numbers
          }
      });
  
      Input.keyMapper[8]  = 'backspace';
      Input.keyMapper[13] = 'enter';
      Input.keyMapper[16] = 'shift';
      Input.keyMapper[18] = 'alt';
      Input.keyMapper[27] = 'escape';
      Input.keyMapper[32] = 'space';
      Input.keyMapper[46] = 'delete';
      Input.keyMapper[37] = 'left';
      Input.keyMapper[38] = 'up';
      Input.keyMapper[39] = 'right';
      Input.keyMapper[40] = 'down';
  
  };
  
  Scene_Notepad.prototype.update = function() {
      Scene_MenuBase.prototype.update.call(this);
      if(this._titleWindow.active || this._detailsWindow.active) {
          this.processCursorBlink();
          this.checkTextInput();
      }
  };
  
  Scene_Notepad.prototype.processCursorBlink = function() {
      this._frameCounter++;
      this._frameCounter %= this._blinkRate;
      if(this._frameCounter === 0) {
          this._activeWindow.cursorToggle();
      }
  };
  
  Scene_Notepad.prototype.checkTextInput = function() {
      this.checkCharacters();
      this.checkSpecialKeys();
      this.checkArrowKeys();
      this.checkShiftKey();
      this.checkAltKey();
      this.checkEnterKey();
      this.checkEscapeKey();
  };
  
  Scene_Notepad.prototype.checkCharacters = function() {
      ALOE.PlayerNotepad.params.inputcodes.forEach(function(a){
          if(Input.isRepeated(a.c)){
              this.bounceCursor();
              if(this._isShifted && this._isAlted) {
                  if (a.sa) {this._activeWindow.addChar(a.sa);}
                  else if (a.s) {this._activeWindow.addChar(a.s);}
                  else {this._activeWindow.addChar(a.c);}
              } else if (this._isShifted) {
                  if (a.s) {this._activeWindow.addChar(a.s);}
                  else {this._activeWindow.addChar(a.c);}
              } else if (this._isAlted) {
                  if (a.a) {this._activeWindow.addChar(a.a);}
                  else {this._activeWindow.addChar(a.c);}
              } else {
                  this._activeWindow.addChar(a.c);
              }
          }
          if(Input.isRepeated("." + a.c)) { //Input class doesn't like pure numbers
              this.bounceCursor();
              if(this._isShifted) {
                  this._activeWindow.addChar(a.s);
              } else {
                  this._activeWindow.addChar(a.c);
              }
          }
      }, this);
  };
  
  Scene_Notepad.prototype.checkSpecialKeys = function() {
      if(Input.isRepeated("space")) {
          this.bounceCursor();
          this._activeWindow.addChar(" ");
      }
      if(Input.isRepeated("backspace")) {
          this.bounceCursor();
          this._activeWindow.backspace();
      }
      if(Input.isRepeated("delete")) {
          this.bounceCursor();
          this._activeWindow.deleteChar();
      }
  };
  
  Scene_Notepad.prototype.checkArrowKeys = function() {
      if(Input.isRepeated("left")) {
          this.processLeft();
          this.bounceCursor();
      }
      if(Input.isRepeated("right")) {
          this.processRight();
          this.bounceCursor();
      }
      if(Input.isRepeated("down")) {
          if(this._detailsWindow.active) {
              this.processDown();
              this.bounceCursor();
          }
      }
      if(Input.isRepeated("up")) {
          if(this._detailsWindow.active) {
              this.processUp();
              this.bounceCursor();
          }
      }
  };
  
  Scene_Notepad.prototype.checkShiftKey = function() {
      if(this._isShifted) {
          if(!Input.isPressed("shift")) {this._isShifted = false;}
      } else {
          if(Input.isPressed("shift")) {this._isShifted = true;}
      }
  };
  
  Scene_Notepad.prototype.checkAltKey = function() {
      if(this._isAlted) {
          if(!Input.isPressed("alt")) {this._isAlted = false;}
      } else {
          if(Input.isPressed("alt")) {this._isAlted = true;}
      }
  }
  
  Scene_Notepad.prototype.checkEnterKey = function() {
      if(Input.isRepeated("enter")) {
          if(this._titleWindow.active) {
              if(this._titleWindow.valid()) {
                  this.processEnterFromTitle();
              } else {
                  this.processInvalidTitle();
              }
          } else if(this._detailsWindow.active) {
              this.bounceCursor();
              this.processEnterFromDetails();
          }
      }
  };
  
  Scene_Notepad.prototype.checkEscapeKey = function() {
      if(Input.isTriggered("escape")) {
          if(this._titleWindow.active) {
              this.processEscapeFromTitle();
          } else if(this._detailsWindow.active) {
              this.processEscapeFromDetails();
          }
      }
  };
  
  Scene_Notepad.prototype.processEnterFromTitle = function() {
      var id = parseInt(this._commandWindow._lastCommandSymbol.slice(2));
      if (id) { //If the note already exists
          if ($gameNotepad.isNoteDetailsModifiable(id)) {
              this._titleWindow.deactivate();
              this._titleWindow.refresh();
              this._detailsWindow.activate();
              this._detailsWindow.refresh();
              this._helpWindow.setDetailsText();
              this._activeWindow = this._detailsWindow;
              SoundManager.playOk();
          } else {
              this._confirmCommandWindow.show();
              this._confirmCommandWindow.activate();
              this._titleWindow.deactivate();
              this._activeWindow = null;
              this._helpWindow.clear();
              SoundManager.playOk();
              this.resetInputMapper();
              this._confirmCommandWindow.select(0);
          }
      } else { //If it is a new note
          this._titleWindow.deactivate();
          this._titleWindow.refresh();
          this._detailsWindow.activate();
          this._detailsWindow.refresh();
          this._helpWindow.setDetailsText();
          this._activeWindow = this._detailsWindow;
          SoundManager.playOk();
      }
  };
  
  Scene_Notepad.prototype.processInvalidTitle = function() {
      SoundManager.playBuzzer();
      //this._helpWindow.setTitleInvalidText(); //not supported yet
  };
  
  Scene_Notepad.prototype.processEnterFromDetails = function() {
      this._activeWindow.newLine();
      SoundManager.playCursor();
  };
  
  Scene_Notepad.prototype.processEscapeFromTitle = function() {
      //Reset the $gameNotepad data
      var id = parseInt(this._commandWindow._lastCommandSymbol.slice(2));
      if (id) {
          $gameNotepad.modifyNoteById(id, this._tempTitle, this._tempDetails);
      }
      //Show/Activate windows
      this._titleWindow.deactivate();
      this._activeWindow = null;
      this._titleWindow.clear();
      this._helpWindow.clear();
      this._commandWindow.activate();
      this._commandWindow.selectLast();
      //Play Cancel sound
      SoundManager.playCancel();
      //Reset Input
      this.resetInputMapper();
      Input.clear();
  };
  
  Scene_Notepad.prototype.processEscapeFromDetails = function() {
      //Show/activate windows
      this._detailsWindow.deactivate();
      this._activeWindow = null;
      this._helpWindow.clear();
      this._confirmCommandWindow.show();
      this._confirmCommandWindow.activate();
      this._confirmCommandWindow.select(0);
      //Play OK sound
      SoundManager.playOk();
      //Reset Input
      this.resetInputMapper();
      Input.clear();
  };
  
  Scene_Notepad.prototype.processDown = function() {
      if(this._activeWindow._row < this._activeWindow.text.length - 1) {
          this._activeWindow._row++;
      }
      if(this._activeWindow._index > this._activeWindow.text[this._activeWindow._row].length) {
          this._activeWindow._index = this._activeWindow.text[this._activeWindow._row].length;
      }
  };
  
  Scene_Notepad.prototype.processLeft = function() {
      if(this._activeWindow._index !== 0) {
          this._activeWindow._index--;
      } else if (this._activeWindow._index === 0 && this._activeWindow._row !== 0) {
          this._activeWindow._row--;
          this._activeWindow._index = this._activeWindow.text[this._activeWindow._row].length;
      }
  };
  
  Scene_Notepad.prototype.processRight = function() {
      if(this._activeWindow.checkRight()) {
          this._activeWindow._index++;
      } else if (this._activeWindow._index === this._activeWindow.text[this._activeWindow._row].length &&
          this._activeWindow._row < this._activeWindow.text.length - 1) {
              this._activeWindow._row++;
              this._activeWindow._index = 0;
      }
  };
  
  Scene_Notepad.prototype.processUp = function() {
      if(this._activeWindow._row !== 0) {
          this._activeWindow._row--;
      }
      if(this._activeWindow._index > this._activeWindow.text[this._activeWindow._row].length) {
          this._activeWindow._index = this._activeWindow.text[this._activeWindow._row].length;
      }
  };
  
  Scene_Notepad.prototype.bounceCursor = function() {
      this._activeWindow.cursorOn();
      this.resetFrameCounter();
      this._activeWindow.refresh();
  };
  
  Scene_Notepad.prototype.resetFrameCounter = function() {
      this._frameCounter = 0;
  };
  
  //=============================================================================
  // Window_NotepadCommand
  //=============================================================================
  // This window contains a command to add a new note and to modify/delete
  // existing notes.
  //=============================================================================
  
  function Window_NotepadCommand() {
      this.initialize.apply(this, arguments);
  }
  
  Window_NotepadCommand.prototype = Object.create(Window_Command.prototype);
  Window_NotepadCommand.prototype.constructor = Window_NotepadCommand;
  
  Window_NotepadCommand.prototype.initialize = function(x, y) {
      Window_Command.prototype.initialize.call(this, x, y);
      this.selectLast();
  };
  
  Window_NotepadCommand._lastCommandSymbol = null;
  
  Window_NotepadCommand.initCommandPosition = function() {
      this._lastCommandSymbol = null;
  };
  
  Window_NotepadCommand.prototype.windowWidth = function() {
      return Graphics.width / 3;
  };
  
  Window_NotepadCommand.prototype.windowHeight = function() {
      return Graphics.height;
  };
  
  Window_NotepadCommand.prototype.numVisibleRows = function() {
      return this.maxItems();
  };
  
  Window_NotepadCommand.prototype.makeCommandList = function() {
      this.addNewNoteCommand();
      this.addExistingNotesCommands();
  };
  
  Window_NotepadCommand.prototype.addNewNoteCommand = function() {
      this.addCommand(ALOE.PlayerNotepad.params.newNote, 'newnote', $gameNotepad.newEnabled());
  };
  
  Window_NotepadCommand.prototype.addExistingNotesCommands = function() {
      var allNotes = $gameNotepad.allNotes().filter(function(a){
          if(!a.hidden){return a;}});
      for (var i = 0; i < allNotes.length; i++) {
          var enabled = (!allNotes[i].titleLocked || !allNotes[i].detailsLocked || !allNotes[i].deleteLocked);
          this.addCommand(allNotes[i].title, 'id' + allNotes[i].id, enabled);
      }
  };
  
  Window_NotepadCommand.prototype.processOk = function() {
      Window_NotepadCommand._lastCommandSymbol = this.currentSymbol();
      Window_Command.prototype.processOk.call(this);
  };
  
  Window_NotepadCommand.prototype.selectLast = function() {
      this.selectSymbol(Window_NotepadCommand._lastCommandSymbol);
  };
  
  Window_NotepadCommand.prototype.select = function(index) {
      Window_Selectable.prototype.select.call(this, index);
      this.updateNotesWindows();
  };
  
  Window_NotepadCommand.prototype.updateNotesWindows = function() {
      if(this.currentSymbol()) {
          var id = parseInt(this.currentSymbol().slice(2));
          if(this._subTitleWindow) {
              if (ALOE.PlayerNotepad.params.fadeLockedText) {
                  if (id && !$gameNotepad.isNoteTitleModifiable(id)) {
                      this._subTitleWindow.setFaded();
                  } else {
                      this._subTitleWindow.setNotFaded();
                  }
              }
              this._subTitleWindow.text = $gameNotepad.titleById(id);
              this._subTitleWindow.refresh();
          }
          if(this._subDetailsWindow) {
              if (ALOE.PlayerNotepad.params.fadeLockedText) {
                  if (id && !$gameNotepad.isNoteDetailsModifiable(id)) {
                      this._subDetailsWindow.setFaded();
                  } else {
                      this._subDetailsWindow.setNotFaded();
                  }
              }
              this._subDetailsWindow.text = $gameNotepad.detailsById(id);
              this._subDetailsWindow.refresh();
          }
      }
  };
  
  Window_NotepadCommand.prototype.removeCommand = function(symbol) {
      var index = this._list.map(function(a){return a.symbol;}).indexOf(symbol);
      this._list.splice(index, 1);
  };
  
  Window_NotepadCommand.prototype.drawItem = function(index) {
      var rect = this.itemRectForText(index);
      var align = this.itemTextAlign();
      this.resetTextColor();
      if(ALOE.PlayerNotepad.params.newNoteColor !== 0 && index === 0) {
          this.changeTextColor(this.textColor(ALOE.PlayerNotepad.params.newNoteColor));
      }
      this.changePaintOpacity(this.isCommandEnabled(index));
      this.drawText(this.commandName(index), rect.x, rect.y, rect.width, align);
      this.resetTextColor();
  };
  
  //=============================================================================
  // Window_NotepadBase
  //=============================================================================
  // Defines common methods to use in both the title and details windows.
  //=============================================================================
  
  function Window_NotepadBase() {
      this.initialize.apply(this, arguments);
  }
  
  Window_NotepadBase.prototype = Object.create(Window_Base.prototype);
  Window_NotepadBase.prototype.constructor = Window_NotepadTitle;
  
  Window_NotepadBase.prototype.initialize = function(x, y, width, height) {
      Window_Base.prototype.initialize.call(this, x, y, width, height);
      this._index = 0;
      this._row = 0;
      this.text = [""];
      this._cursorActive = false;
      this._faded = false;
      this.deactivate();
  };
  
  Window_NotepadBase.prototype.addChar = function(ch) {
      var index = this._index;
      var maxLength = this._maxLength;
      var text = this.text[this._row];
      if (maxLength === 0 || text.length < maxLength) {
          this.text[this._row] = text.slice(0, index) + ch + text.slice(index);
          this._index++;
          this.refresh();
      }
  };
  
  Window_NotepadBase.prototype.backspace = function() {
      var index = this._index;
      var row = this._row;
      var text = this.text[row];
      if(index !== 0) {
          this.text[row] = text.slice(0, index - 1) + text.slice(index);
          this._index--;
          this.refresh();
      } else if (row !== 0) {
          this._index = this.text[this._row - 1].length;
          this._row--;
          this.text[row - 1] += this.text[row];
          for (var i = row; i < this.text.length - 1; i++) {
              this.text[i] = this.text[i + 1];
          }
          this.text.pop();
          this.refresh()
      }
  };
  
  Window_NotepadBase.prototype.deleteChar = function() {
      var index = this._index;
      var thisLine = this.text[this._row];
      var row = this._row;
      if(index < thisLine.length) {
          this.text[row] = thisLine.slice(0, index) + thisLine.slice(index + 1);
          this.refresh();
      } else if (index === thisLine.length && this.text.length > 1 && row !== this.text.length - 1) {
          this.text[row] += this.text[row + 1];
          for (var i = row + 1; i < this.text.length - 1; i++) {
              this.text[i] = this.text[i + 1];
          }
          this.text.pop();
          this.refresh();
      }
  };
  
  Window_NotepadBase.prototype.refresh = function() {
      this.contents.clear();
      var lineHeight = this.lineHeight();
      this.changePaintOpacity(!this._faded);
      for(var i = 0; i < this.text.length; i++) {
          this.drawText(this.text[i], 0, lineHeight * i);
      }
      this.changePaintOpacity(true);
      if(this._cursorActive) {
          this.drawTextCursor();
      }
  };
  
  Window_NotepadBase.prototype.clear = function() {
      this.text = [""];
      this._index = 0;
      this._row = 0;
      this.refresh();
  };
  
  Window_NotepadBase.prototype.drawTextCursor = function() {
      if(this.active) {
          var index = this._index;
          var row = this._row;
          var text = this.text[row];
          var textWidth = this.textWidth(text.slice(0,index));
          var offset = ALOE.PlayerNotepad.params.cursorOffset;
          var lineHeight = this.lineHeight();
          this.drawText("|", textWidth + offset, row * lineHeight);
      }
  };
  
  Window_NotepadBase.prototype.checkRight = function() {
      return ((this._maxLength === 0 || this._index < this._maxLength) && 
          this._index < this.text[this._row].length);
      //If (details window OR not at the max length) AND (cursor is not at the end)
  };
  
  Window_NotepadBase.prototype.cursorToggle = function() {
      this._cursorActive = !this._cursorActive;
      this.refresh();
  };
  
  Window_NotepadBase.prototype.cursorOn = function() {
      this._cursorActive = true;
  };
  
  Window_NotepadBase.prototype.setFaded = function() {
      this._faded = true;
  };
  
  Window_NotepadBase.prototype.setNotFaded = function() {
      this._faded = false;
  };
  
  //=============================================================================
  // Window_NotepadTitle
  //=============================================================================
  // This window contains the title of the note.
  //=============================================================================
  
  function Window_NotepadTitle() {
      this.initialize.apply(this, arguments);
  }
  
  Window_NotepadTitle.prototype = Object.create(Window_NotepadBase.prototype);
  Window_NotepadTitle.prototype.constructor = Window_NotepadTitle;
  
  Window_NotepadTitle.prototype.initialize = function(x, y, width, height) {
      Window_NotepadBase.prototype.initialize.call(this, x, y, width, height);
      this._maxLength = ALOE.PlayerNotepad.params.maxTitleLength || 35;
      this.refresh();
  };
  
  Window_NotepadTitle.prototype.valid = function() {
      return this.text[this._row].length > 0;
  };
  
  //=============================================================================
  // Window_NotepadDetails
  //=============================================================================
  // This window contains the details of the note.
  //=============================================================================
  
  function Window_NotepadDetails() {
      this.initialize.apply(this, arguments);
  }
  
  Window_NotepadDetails.prototype = Object.create(Window_NotepadBase.prototype);
  Window_NotepadDetails.prototype.constructor = Window_NotepadDetails;
  
  Window_NotepadDetails.prototype.initialize = function(x, y, width, height) {
      Window_NotepadBase.prototype.initialize.call(this, x, y, width, height);
      this._row = 0;
      this._maxLength = 0;
  };
  
  Window_NotepadDetails.prototype.newLine = function() {
      var nextLineString = this.text[this._row].slice(this._index);
      this.text[this._row] = this.text[this._row].substr(0, this._index);
      this.text.splice(this._row + 1, 0, nextLineString);
      this._row++;
      this._index = 0;
      this.refresh();
  };
  
  //=============================================================================
  // Window_NotepadHelp
  //=============================================================================
  // This window shows directions to the player.
  //=============================================================================
  
  function Window_NotepadHelp() {
      this.initialize.apply(this, arguments);
  }
  
  Window_NotepadHelp.prototype = Object.create(Window_Help.prototype);
  Window_NotepadHelp.prototype.constructor = Window_NotepadHelp;
  
  Window_NotepadHelp.prototype.initialize = function(x, width) {
      var height = this.fittingHeight(2);
      var y = Graphics.height - height;
      Window_Base.prototype.initialize.call(this, x, y, width, height);
      this._text = '';
  };
  
  Window_NotepadHelp.prototype.setTitleText = function() {
      var text = ALOE.PlayerNotepad.params.titleInstructions;
      this.setText(text);
  };
  
  //Not used yet. 
  Window_NotepadHelp.prototype.setTitleInvalidText = function() {
      var text = "Note title cannot be empty.";
      this.setText(text);
  };
  
  Window_NotepadHelp.prototype.setDetailsText = function() {
      var text = ALOE.PlayerNotepad.params.detailsInstructions;
      this.setText(text);
  };
  
  //=============================================================================
  // Window_ExistingNoteChoices
  //=============================================================================
  // This window shows choice to modify or delete an existing note.
  //=============================================================================
  
  function Window_ExistingNoteCommand() {
      this.initialize.apply(this, arguments);
  }
  
  Window_ExistingNoteCommand.prototype = Object.create(Window_Command.prototype);
  Window_ExistingNoteCommand.prototype.constructor = Window_ExistingNoteCommand;
  
  Window_ExistingNoteCommand.prototype.initialize = function(x, y) {
      Window_Command.prototype.initialize.call(this, x, y);
  };
  
  Window_ExistingNoteCommand.prototype.windowWidth = function() {
      return Graphics.width / 3;
  };
  
  Window_ExistingNoteCommand.prototype.windowHeight = function() {
      return this.fittingHeight(this.numVisibleRows());
  };
  
  Window_ExistingNoteCommand.prototype.numVisibleRows = function() {
      return this.maxItems();
  };
  
  Window_ExistingNoteCommand.prototype.makeCommandList = function() {
      var modifyEnabled = true;
      var deleteEnabled = true;
      if(SceneManager._scene._commandWindow._lastCommandSymbol) {
          var id = parseInt(SceneManager._scene._commandWindow._lastCommandSymbol.slice(2));
          if (id) {
              modifyEnabled = $gameNotepad.isNoteModifiable(id);
              deleteEnabled = $gameNotepad.isNoteDeletable(id);
          }
      }
      this.addCommand(ALOE.PlayerNotepad.params.modifyNote, 'modify', modifyEnabled);
      this.addCommand(ALOE.PlayerNotepad.params.deleteNote, 'delete', deleteEnabled);
  };
  
  Window_ExistingNoteCommand.prototype.drawItem = function(index) {
      var rect = this.itemRectForText(index);
      var align = this.itemTextAlign();
      this.resetTextColor();
      if(ALOE.PlayerNotepad.params.modifyNoteColor !== 0 && index === 0) {
          this.changeTextColor(this.textColor(ALOE.PlayerNotepad.params.modifyNoteColor));
      } else if (ALOE.PlayerNotepad.params.deleteNoteColor !== 0 && index === 1) {
          this.changeTextColor(this.textColor(ALOE.PlayerNotepad.params.deleteNoteColor));
      }
      this.changePaintOpacity(this.isCommandEnabled(index));
      this.drawText(this.commandName(index), rect.x, rect.y, rect.width, align);
      this.resetTextColor();
  };
  
  //=============================================================================
  // Window_ConfirmChangesCommand
  //=============================================================================
  // This window shows the choice to save or discard changes to the note.
  //=============================================================================
  
  function Window_ConfirmChangesCommand() {
      this.initialize.apply(this, arguments);
  }
  
  Window_ConfirmChangesCommand.prototype = Object.create(Window_Command.prototype);
  Window_ConfirmChangesCommand.prototype.constructor = Window_ConfirmChangesCommand;
  
  Window_ConfirmChangesCommand.prototype.initialize = function(x, y) {
      Window_Command.prototype.initialize.call(this, x, y);
  };
  
  Window_ConfirmChangesCommand.prototype.windowWidth = function() {
      return Graphics.width / 3;
  };
  
  Window_ConfirmChangesCommand.prototype.windowHeight = function() {
      return this.fittingHeight(this.numVisibleRows());
  };
  
  Window_ConfirmChangesCommand.prototype.numVisibleRows = function() {
      return this.maxItems();
  };
  
  Window_ConfirmChangesCommand.prototype.makeCommandList = function() {
      this.addCommand(ALOE.PlayerNotepad.params.saveNote, 'save', true);
      this.addCommand(ALOE.PlayerNotepad.params.discardChanges, 'discard', true);
  };
  
  Window_ConfirmChangesCommand.prototype.drawItem = function(index) {
      var rect = this.itemRectForText(index);
      var align = this.itemTextAlign();
      this.resetTextColor();
      if(ALOE.PlayerNotepad.params.saveNoteColor !== 0 && index === 0) {
          this.changeTextColor(this.textColor(ALOE.PlayerNotepad.params.saveNoteColor));
      } else if (ALOE.PlayerNotepad.params.discardChangesColor !== 0 && index === 1) {
          this.changeTextColor(this.textColor(ALOE.PlayerNotepad.params.discardChangesColor));
      }
      this.changePaintOpacity(this.isCommandEnabled(index));
      this.drawText(this.commandName(index), rect.x, rect.y, rect.width, align);
      this.resetTextColor();
  };
  
  Window_ConfirmChangesCommand.prototype.playOkSound = function() {
      if(this.currentSymbol() === "save") {
          SoundManager.playSave();
      } else if (this.currentSymbol() === "discard") {
          SoundManager.playCancel();
      } else {
          SoundManager.playOk();
      }
  };
  
  //=============================================================================
  // Main Menu Integration
  //=============================================================================
  // Alias of Scene_Menu and Window_MenuCommand to add the Notepad command to
  // the main menu.
  //=============================================================================
  
  if(ALOE.PlayerNotepad.params.addToMenu) {
  
  ALOE.Alias.Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow;
  Scene_Menu.prototype.createCommandWindow = function() {
      ALOE.Alias.Scene_Menu_createCommandWindow.call(this);
      this._commandWindow.setHandler('notepad',   this.commandNotepad.bind(this));
  };
  
  Scene_Menu.prototype.commandNotepad = function() {
      SceneManager.push(Scene_Notepad);
  };
  
  ALOE.Alias.Window_MenuCommand_addOriginalCommands = Window_MenuCommand.prototype.addOriginalCommands;
  Window_MenuCommand.prototype.addOriginalCommands = function() {
      ALOE.Alias.Window_MenuCommand_addOriginalCommands.call(this);
      var visible = true;
      var enabled = true;
      var switchForVisible = ALOE.PlayerNotepad.params.switchForVisible;
      var switchForEnabled = ALOE.PlayerNotepad.params.switchForEnabled;
      if (switchForVisible !== 0 && switchForVisible !== undefined) {
          visible = $gameSwitches.value(switchForVisible);
      }
      if (switchForEnabled !== 0 && switchForEnabled !== undefined) {
          enabled = $gameSwitches.value(switchForEnabled);
      }
      if (visible) {
          this.addCommand(ALOE.PlayerNotepad.params.menuCommandName, 'notepad', enabled);
      }
  };
  
  }
  
  //=============================================================================
  // Plugin Commands
  //=============================================================================
  // Define the functions that are executed for the plugin commands.
  //=============================================================================
  
  ALOE.Alias.Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function(command, args) {
      ALOE.Alias.Game_Interpreter_pluginCommand.call(this, command, args);
      if(command.toLowerCase() === "notepad") {
          switch (args[0].toLowerCase()) {
              case "open":
                  SceneManager.push(Scene_Notepad);
                  break;
              case "delete":
                  switch (args[1].toLowerCase()) {
                      case "key":
                          $gameNotepad.deleteNoteByKey(args[2].toLowerCase());
                          break;
                      case "all":
                          $gameNotepad.deleteAllNotes();
                          break;
                      default:
                          break;    
                  }
                  break;
              case "stage":
                  var prop = args[1].toLowerCase();
                  switch (prop) {
                      case "title":
                          $gameNotepad.setStage(prop, [args.slice(2).join(" ")]);
                          break;
                      case "details":
                          $gameNotepad.setStage(prop, args.slice(2).join(" ").split("\\n"));
                          break;
                      case "key":
                          $gameNotepad.setStage(prop, args[2].toLowerCase()); 
                          break;
                      case "bothlocked":
                          var bothLocked = args[2].toLowerCase() === "true" ? true : false;
                          $gameNotepad.setStage("titleLocked", bothLocked);
                          $gameNotepad.setStage("detailsLocked", bothLocked);
                          break;
                      case "titlelocked":
                          var titleLocked = args[2].toLowerCase() === "true" ? true : false;
                          $gameNotepad.setStage(prop, titleLocked);
                          break;
                      case "detailslocked":
                          var detailsLocked = args[2].toLowerCase() === "true" ? true : false;
                          $gameNotepad.setStage(prop, detailsLocked);
                          break;
                      case "deletelocked":
                          var deleteLocked = args[2].toLowerCase() === "true" ? true : false;
                          $gameNotepad.setStage(prop, deleteLocked);
                          break;
                      case "hidden":
                          var hidden = args[2].toLowerCase() === "true" ? true : false;
                          $gameNotepad.setStage(prop, hidden);
                          break;
                      case "add":
                          var title         = $gameNotepad.getStage("title");
                          var details       = $gameNotepad.getStage("details");
                          var key           = $gameNotepad.getStage("key");
                          var titleLocked   = $gameNotepad.getStage("titleLocked");
                          var detailsLocked = $gameNotepad.getStage("detailsLocked");
                          var deleteLocked  = $gameNotepad.getStage("deleteLocked");
                          var hidden        = $gameNotepad.getStage("hidden");
                          if((title) && (key)) {
                              if($gameNotepad.keyExists(key)) {
                                  $gameNotepad.modifyNoteByKey(key, title, details, titleLocked,
                                       detailsLocked, deleteLocked, hidden);
                              } else {
                                  $gameNotepad.addNote(title, details, key, titleLocked,
                                       detailsLocked, deleteLocked, hidden);
                              }
                              $gameNotepad.clearStage();
                          }
                          break;
                      case "append":
                          var key          = $gameNotepad.getStage("key");
                          var title        = $gameNotepad.getStage("title");
                          var details      = $gameNotepad.getStage("details");
                          if (key) {
                              if ($gameNotepad.keyExists(key)) {
                                  $gameNotepad.appendNoteByKey(key, title, details)
                              }
                              $gameNotepad.clearStage();
                          }
                      default:
                          break;
                  }   
                  break;
              case "lock":
                  switch(args[1].toLowerCase()) {
                      case "title":
                          $gameNotepad.lockTitle(args[2].toLowerCase());
                          break;
                      case "details":
                          $gameNotepad.lockDetails(args[2].toLowerCase());
                          break;
                      case "both":
                          $gameNotepad.lockTitle(args[2].toLowerCase());
                          $gameNotepad.lockDetails(args[2].toLowerCase());
                          break;
                      case "delete":
                          $gameNotepad.lockDelete(args[2].toLowerCase());
                          break;
                      default:
                          break;
                  }
                  break;
              case "unlock":
                  switch(args[1].toLowerCase()) {
                      case "title":
                          $gameNotepad.unlockTitle(args[2].toLowerCase());
                          break;
                      case "details":
                          $gameNotepad.unlockDetails(args[2].toLowerCase());
                          break;
                      case "both":
                          $gameNotepad.unlockTitle(args[2].toLowerCase());
                          $gameNotepad.unlockDetails(args[2].toLowerCase());
                          break;
                      case "delete":
                          $gameNotepad.unlockDelete(args[2].toLowerCase());
                          break;
                      default:
                          break;
                  }
                  break;
              case "hide":
                  $gameNotepad.hide(args[1].toLowerCase());
                  break;
              case "show":
                  $gameNotepad.show(args[1].toLowerCase());
                  break;
              case "disable":
                  $gameNotepad.disableFeature(args[1].toLowerCase());
                  break;
              case "enable":
                  $gameNotepad.enableFeature(args[1].toLowerCase());
                  break;
              case "search":
                  var variableId = parseInt(args[1]);
                  switch (args[2].toLowerCase()) {
                      case "titles":
                          if(args[3] === "for") {
                              var term = args.slice(4).join(" ");
                              $gameNotepad.searchTitles(term, variableId);
                          }
                          break;
                      case "details":
                          if(args[3] === "for") {
                              var term = args.slice(4).join(" ");
                              $gameNotepad.searchDetails(term, variableId);
                          }
                          break;
                      case "key":
                          var key = args[3];
                          if(args[4] === "for") {
                              var term = args.slice(5).join(" ");
                              $gameNotepad.searchKey(key, term, variableId);
                          }
                          break;
                      default:
                          break;
                  }
              default:
                  break;
          }
      }
  };
  
  (function() {
      if (ALOE.PlayerNotepad.params.testmode === true) {
          ALOE.Alias.Input_onKeyDown = Input._onKeyDown;
          Input._onKeyDown = function(event) {
              ALOE.Alias.Input_onKeyDown.call(this, event);
              console.log(event.keyCode);
          };
      }
  })();