import { ActionClear } from './ActionClear' ; import { UserManager } from './UserManager' ; import { OperationAddAction } from './OperationAddAction' ; import { CancelStack } from './CancelStack' ; import { ActionMagnetDelete } from './ActionMagnetDelete' ; import { ActionMagnetNew } from './ActionMagnetNew' ; import { MagnetManager } from './magnetManager' ; import { AnimationToolBar } from './AnimationToolBar' ; import { getCanvas } from "./main" ; import { Share } from "./share" ; import { Layout } from './Layout' ; import { Timeline } from './Timeline' ; import { Action } from './Action' ; import { ActionMagnetMove } from './ActionMagnetMove' ; import { Operation } from 'Operation' ; import { AnimationManager } from './AnimationManager' ; /**
 * Manage the board
 */ export class BoardManager { static readonly MAGNETCANCELLABLE = true ; /** name of the board. Default is 0 (this name is used for storing in localStorage) */ static boardName = "0" ; /** timeline of actions */ static timeline = new Timeline ( ) ; /** stack to store the cancel/redo operations */ static cancelStack = new CancelStack ( ) ; /**
   * initialization (button)
   */ static init ( ) { document . getElementById ( "blackboardClear" ) . onclick = ( ) => { if ( confirm ( "Do you want to clear and reset the board?" ) ) Share . execute ( "boardReset" , [ ] ) ; } ; } /**
    * erase the board
    */ static _reset ( ) { const canvas = getCanvas ( ) ; canvas . width = canvas . width + 0 ; MagnetManager . resetMagnets ( ) ; BoardManager . timeline . clear ( ) ; BoardManager . cancelStack = new CancelStack ( ) ; AnimationToolBar . update ( ) ; } param atLeastWidth description static setWidthAtLeast ( atLeastWidth ) { const canvas = getCanvas ( ) ; if ( canvas . width < atLeastWidth ) { canvas . width = atLeastWidth ; BoardManager . timeline . canvasRedraw ( ) ; } } param a returns static _createCanvasForRectangle ( r ) { const C = document . createElement ( "canvas" ) ; C . width = r . x2 - r . x1 ; C . height = r . y2 - r . y1 ; const ctx = C . getContext ( "2d" ) ; ctx . drawImage ( getCanvas ( ) , r . x1 , r . y1 , r . x2 - r . x1 , r . y2 - r . y1 , 0 , 0 , r . x2 - r . x1 , r . y2 - r . y1 ) ; return C ; } param { * } r description static _toBlobOfRectangle ( r , callback ) { BoardManager . _createCanvasForRectangle ( r ) . toBlob ( callback ) ; } param { * } r returns static getDataURLOfRectangle ( r ) { return BoardManager . _createCanvasForRectangle ( r ) . toDataURL ( ) ; } param action param executeAgain description static addAction ( action , executeAgain = true ) { if ( ! BoardManager . MAGNETCANCELLABLE ) if ( action instanceof ActionMagnetNew || action instanceof ActionMagnetMove || action instanceof ActionMagnetDelete ) return ; const operation = new OperationAddAction ( action , BoardManager . timeline . getCurrentIndex ( ) + 1 ) ; if ( action . userid == UserManager . me . userID ) BoardManager . cancelStack . push ( operation ) ; BoardManager . setWidthAtLeast ( action . xMax ) ; BoardManager . timeline . insertActionNowAlreadyExecuted ( action , executeAgain ) ; } static executeOperation ( operation ) { operation . redo ( ) ; BoardManager . cancelStack . push ( operation ) ; } static getLastAction ( ) { return BoardManager . timeline . getLastAction ( ) ; } static getCurrentScreenRectangle ( ) { const container = document . getElementById ( "container" ) ; const x1 = container . scrollLeft ; const y1 = container . scrollTop ; const x2 = x1 + Layout . getWindowWidth ( ) ; const y2 = y1 + Layout . getWindowHeight ( ) ; return { x1 : x1 , y1 : y1 , x2 : x2 , y2 : y2 } ; } /**
     * load the board from the local storage
     */ static load ( data = localStorage . getItem ( Share . getTableauNoirID ( ) ) ) { if ( data != undefined ) { try { BoardManager . timeline . clearAndReset ( data ) ; } catch ( e ) { } } else { BoardManager . _reset ( ) ; } } /**
     *
     */ static async cancel ( userid ) { if ( ! BoardManager . cancelStack . canUndo ( ) ) return ; BoardManager . cancelStack . undo ( ) ; } /**
     *
     */ static async redo ( userid ) { if ( ! BoardManager . cancelStack . canRedo ( ) ) return ; BoardManager . cancelStack . redo ( ) ; } static async previousPausedFrame ( ) { AnimationManager . end ( ) ; await BoardManager . timeline . previousPausedFrame ( ) ; AnimationToolBar . updateCurrentIndex ( ) ; } decription static async nextPausedFrame ( ) { if ( AnimationManager . isRunning ) AnimationManager . end ( ) ; else { AnimationManager . begin ( ) ; await BoardManager . timeline . nextPausedFrame ( ) ; AnimationManager . end ( ) ; AnimationToolBar . updateCurrentIndex ( ) ; } } description static fastNextPausedFrame ( ) { AnimationManager . end ( ) ; BoardManager . timeline . nextPausedFrame ( ) ; AnimationToolBar . updateCurrentIndex ( ) ; } private static get widthFromActions ( ) : number { return Math . max ( ... this . timeline . actions . map ( ( a ) => a . xMax ) ) ; } private static get widthFromMagnets ( ) : number { const magnets = MagnetManager . getMagnets ( ) ; let max = 0 ; for ( let i = 0 ; i < magnets . length ; i ++ ) max = Math . max ( max , magnets [ i ] . offsetLeft + magnets [ i ] . offsetWidth ) ; return max ; } param userid description static newSlideAndClear ( userid ) { BoardManager . timeline . getLastAction ( ) . pause = true ; document . getElementById ( "content" ) . style . filter = "invert(0.5)" ; BoardManager . addAction ( new ActionClear ( userid ) ) ; setTimeout ( ( ) => document . getElementById ( "content" ) . style . filter = "" , 100 ) ; } static get width ( ) : number { return Math . max ( BoardManager . widthFromActions , BoardManager . widthFromMagnets ) ; } } window [ "BoardManager" ] = BoardManager ;