import { fabric } from 'fabric' ; import * as uuid from 'uuid' ; import { concat , filter , pull , includes , orderBy } from 'lodash' ; import { SentenceStorage , WordStorage } from '../../../../core/storage/storage.model' ; import { Word } from './word.model' ; import { Glyph } from './glyph.model' ; export class Sentence extends fabric . Group { author : string ; canvas : fabric . Canvas ; created : number ; expanded : boolean ; id : string ; order : number ; selected : boolean ; tid : string ; interpretation : string ; transliteration : string ; words : Array < Word [ 'id' ] > ; private wordsCache : Array < Word > ; private glyphsCache : Array < Glyph > ; constructor ( sentenceStorage , canvas ) { super ( ) ; this . canvas = canvas ; sentenceStorage = sentenceStorage || { author : '' , created : new Date ( ) . getTime ( ) , words : [ ] , order : 0 , position : { top : 0 , left : 0 , width : 0 , height : 0 , } , interpretation : '' , transliteration : '' , } ; this . evented = false ; this . hasBorders = false ; this . hasControls = false ; this . hoverCursor = 'pointer' ; this . lockMovementX = true ; this . lockMovementY = true ; this . lockRotation = true ; this . lockScalingX = true ; this . lockScalingY = true ; this . selectable = false ; this . author = sentenceStorage . author ; this . created = sentenceStorage . created ; this . expanded = true ; this . id = uuid ( ) ; this . order = sentenceStorage . order ; this . selected = false ; this . tid = 'sentence' ; this . interpretation = sentenceStorage . interpretation ; this . transliteration = sentenceStorage . transliteration ; this . words = [ ] ; sentenceStorage . words . forEach ( ( wordStorage ) => { this . addWord ( new Word ( wordStorage , this . id , canvas ) ) ; } ) ; } getWords ( rebuildCache = false ) { if ( rebuildCache ) { this . rebuildObjectsCache ( ) ; } return this . wordsCache || [ ] ; } addWord ( word ) { if ( word && this . canvas ) { this . words . push ( word . id ) ; word . order = this . words . length ; this . canvas . add ( word ) ; this . reorderWords ( ) ; } } removeWord ( word ) { if ( word && this . canvas ) { word . getGlyphs ( ) . forEach ( glyph => this . canvas . remove ( glyph ) ) ; this . words = pull ( this . words , word . id ) ; this . canvas . remove ( word ) ; this . reorderWords ( ) ; } } wordCount ( ) { return this . words . length ; } glyphCount ( ) { return this . getGlyphs ( ) . length ; } getGlyphs ( rebuildCache = false ) { if ( rebuildCache ) { this . rebuildObjectsCache ( true ) ; } return this . glyphsCache || [ ] ; } reorderWords ( ) { let cnt = 0 ; this . rebuildObjectsCache ( ) ; this . getWords ( ) . forEach ( ( w ) => { if ( w ) { w . order = cnt ; cnt ++ ; } } ) ; } private rebuildObjectsCache ( rebuildCache = false ) { let glyphs = [ ] ; let words = [ ] ; if ( this . canvas ) { words = orderBy ( filter ( this . canvas . getObjects ( ) , o => { if ( o . tid && o . tid === 'word' && includes ( this . words , o . id ) ) { glyphs = concat ( glyphs , ( < Word > o ) . getGlyphs ( rebuildCache ) ) ; return true ; } return false ; } ) , 'order' ) ; } this . wordsCache = words ; this . glyphsCache = glyphs ; } }