import { Orientation , Render } from '../Render/Render' ; import { Page , PageDensity } from '../Page/Page' ; import { PageFlip } from '../PageFlip' ; import { FlipDirection } from '../Flip/Flip' ; type NumberArray = number [ ] ; /**
 * Сlass representing a collection of pages
 */ export abstract class PageCollection { protected readonly app : PageFlip ; protected readonly render : Render ; protected readonly isShowCover : boolean ; /** Pages List */ protected pages : Page [ ] = [ ] ; /** Index of the current page in list */ protected currentPageIndex = 0 ; /** Number of the current spread in book */ protected currentSpreadIndex = 0 ; /**  Two-page spread in landscape mode */ protected landscapeSpread : NumberArray [ ] = [ ] ; /**  One-page spread in portrait mode */ protected portraitSpread : NumberArray [ ] = [ ] ; protected constructor ( app , render ) { this . render = render ; this . app = app ; this . currentPageIndex = 0 ; this . isShowCover = this . app . getSettings ( ) . showCover ; } /**
     * Load pages
     */ public abstract load ( ) ; /**
     * Clear pages list
     */ public destroy ( ) { this . pages = [ ] ; } /**
     * Split the book on the two-page spread in landscape mode and one-page spread in portrait mode
     */ protected createSpread ( ) { this . landscapeSpread = [ ] ; this . portraitSpread = [ ] ; for ( let i = 0 ; i < this . pages . length ; i ++ ) { this . portraitSpread . push ( [ i ] ) ; } let start = 0 ; if ( this . isShowCover ) { this . pages [ 0 ] . setDensity ( PageDensity . HARD ) ; this . landscapeSpread . push ( [ start ] ) ; start ++ ; } for ( let i = start ; i < this . pages . length ; i += 2 ) { if ( i < this . pages . length - 1 ) this . landscapeSpread . push ( [ i , i + 1 ] ) ; else { this . landscapeSpread . push ( [ i ] ) ; this . pages [ i ] . setDensity ( PageDensity . HARD ) ; } } } /**
     * Get spread by mode (portrait or landscape)
     */ protected getSpread ( ) { return this . render . getOrientation ( ) === Orientation . LANDSCAPE ? this . landscapeSpread : this . portraitSpread ; } param { number } pageNum public getSpreadIndexByPage ( pageNum ) { const spread = this . getSpread ( ) ; for ( let i = 0 ; i < spread . length ; i ++ ) if ( pageNum === spread [ i ] [ 0 ] || pageNum === spread [ i ] [ 1 ] ) return i ; return null ; } /**
     * Get the total number of pages
     */ public getPageCount ( ) { return this . pages . length ; } /**
     * Get the pages list
     */ public getPages ( ) { return this . pages ; } param { number } pageIndex public getPage ( pageIndex ) { if ( pageIndex >= 0 && pageIndex < this . pages . length ) { return this . pages [ pageIndex ] ; } throw new Error ( 'Invalid page number' ) ; } param { Page } current public nextBy ( current ) { const idx = this . pages . indexOf ( current ) ; if ( idx < this . pages . length - 1 ) return this . pages [ idx + 1 ] ; return null ; } param { Page } current public prevBy ( current ) { const idx = this . pages . indexOf ( current ) ; if ( idx > 0 ) return this . pages [ idx - 1 ] ; return null ; } param { FlipDirection } direction public getFlippingPage ( direction ) { const current = this . currentSpreadIndex ; if ( this . render . getOrientation ( ) === Orientation . PORTRAIT ) { return direction === FlipDirection . FORWARD ? this . pages [ current ] . newTemporaryCopy ( ) : this . pages [ current - 1 ] ; } else { const spread = direction === FlipDirection . FORWARD ? this . getSpread ( ) [ current + 1 ] : this . getSpread ( ) [ current - 1 ] ; if ( spread . length === 1 ) return this . pages [ spread [ 0 ] ] ; return direction === FlipDirection . FORWARD ? this . pages [ spread [ 0 ] ] : this . pages [ spread [ 1 ] ] ; } } param { FlipDirection } direction public getBottomPage ( direction ) { const current = this . currentSpreadIndex ; if ( this . render . getOrientation ( ) === Orientation . PORTRAIT ) { return direction === FlipDirection . FORWARD ? this . pages [ current + 1 ] : this . pages [ current - 1 ] ; } else { const spread = direction === FlipDirection . FORWARD ? this . getSpread ( ) [ current + 1 ] : this . getSpread ( ) [ current - 1 ] ; if ( spread . length === 1 ) return this . pages [ spread [ 0 ] ] ; return direction === FlipDirection . FORWARD ? this . pages [ spread [ 1 ] ] : this . pages [ spread [ 0 ] ] ; } } /**
     * Show next spread
     */ public showNext ( ) { if ( this . currentSpreadIndex < this . getSpread ( ) . length ) { this . currentSpreadIndex ++ ; this . showSpread ( ) ; } } /**
     * Show prev spread
     */ public showPrev ( ) { if ( this . currentSpreadIndex > 0 ) { this . currentSpreadIndex -- ; this . showSpread ( ) ; } } /**
     * Get the number of the current spread in book
     */ public getCurrentPageIndex ( ) { return this . currentPageIndex ; } param { number } pageNum public show ( pageNum = null ) { if ( pageNum === null ) pageNum = this . currentPageIndex ; if ( pageNum < 0 || pageNum >= this . pages . length ) return ; const spreadIndex = this . getSpreadIndexByPage ( pageNum ) ; if ( spreadIndex !== null ) { this . currentSpreadIndex = spreadIndex ; this . showSpread ( ) ; } } /**
     * Index of the current page in list
     */ public getCurrentSpreadIndex ( ) { return this . currentSpreadIndex ; } param { number } newIndex public setCurrentSpreadIndex ( newIndex ) { if ( newIndex >= 0 && newIndex < this . getSpread ( ) . length ) { this . currentSpreadIndex = newIndex ; } else { throw new Error ( 'Invalid page' ) ; } } /**
     * Show current spread
     */ private showSpread ( ) { const spread = this . getSpread ( ) [ this . currentSpreadIndex ] ; if ( spread . length === 2 ) { this . render . setLeftPage ( this . pages [ spread [ 0 ] ] ) ; this . render . setRightPage ( this . pages [ spread [ 1 ] ] ) ; } else { if ( this . render . getOrientation ( ) === Orientation . LANDSCAPE ) { if ( spread [ 0 ] === this . pages . length - 1 ) { this . render . setLeftPage ( this . pages [ spread [ 0 ] ] ) ; this . render . setRightPage ( null ) ; } else { this . render . setLeftPage ( null ) ; this . render . setRightPage ( this . pages [ spread [ 0 ] ] ) ; } } else { this . render . setLeftPage ( null ) ; this . render . setRightPage ( this . pages [ spread [ 0 ] ] ) ; } } this . currentPageIndex = spread [ 0 ] ; this . app . updatePageIndex ( this . currentPageIndex ) ; } }