const _ = require('lodash');
const {Text} = require('./paragraph');


class Paratree {
  constructor(text) {
    this.text = text;
    this.paragraphs= new Text(this, this.text);
    return this;
  }
  
  get sentences() {
    return _.chain(this.paragraphs)
      .map(paragraph => paragraph.sentencesCollection)
      .flatten().value();
  }
  
  get words() {
    return _.chain(this.sentences)
      .map(sentence => sentence.wordsCollection)
      .flatten().value();
  }

  findParagraphById(id) {
    return _.find(this.paragraphs, {id});
  }

  findParagraphByIndex(index) {
    return _.find(this.paragraphs, {index});
  }

  findSentenceById(id) {
    return _.find(this.sentences, {id});
  }

  findWordById(id) {
    return _.find(this.words, {id});
  }

  uniqueWords() {
    return _.chain(this.words)
      .map(word => word.clean)
      .map(_.lowerCase).sort().uniq().compact().value();
  }

  charactersLength() {
    return this.text.length;
  }

  charactersNoSpaceLength() {
    return this.text.replace(/\s/ig, '').length;
  }

  longestSentence() {
    return _.chain(this.sentences)
      .orderBy([sentence => sentence.words.length], ['desc']).first().value();
  }

  shortestSentence() {
    return _.chain(this.sentences)
      .orderBy([sentence => sentence.words.length], ['asc']).first().value();
  }

  averageWordSentence() {
    return _.chain(this.sentences)
      .meanBy(o => o.words.length)
      .value();
  }

  averageCharacterSentence() {
    return _.chain(this.sentences)
      .meanBy(o => o.text.length)
      .value();
  }

  averageWordLength() {
    return _.chain(this.words)
      .meanBy(o => o.text.length)
      .value();
  }

  wordOccurences() {
    return _.chain(this.words)
      .map(word => word.clean)
      .map(_.lowerCase).compact().groupBy(o => o)
      .map((v, k) => new Object({word: k, occurence: v.length}))
      .sortBy('occurence')
      .reverse()
      .keyBy('word')
      .mapValues('occurence')
      .value();
  }
}

module.exports = Paratree;

@@ -29,20 +29,22 @@
 %0Aconst %7B
+ 
 Text
+ 
 %7D = requ
@@ -50,16 +50,20 @@
 uire('./
+lib/
 paragrap
@@ -71,48 +71,232 @@
 ');%0A
-%0A%0Aclass Paratree %7B%0A  constructor(text) %7B
+const Data = require('./lib/data');%0Aconst uuidV4 = require('uuid/v4');%0A%0Aconst data = new WeakMap();%0A%0Aclass Paratree %7B%0A  constructor(text) %7B%0A    // add private data%0A    data.set(this, new Data());%0A    %0A    this.id = uuidV4();
 %0A   
@@ -382,24 +382,73 @@
 his;%0A  %7D%0A  %0A
+  get data() %7B%0A    return data.get(this);%0A  %7D%0A  %0A
   get senten

Add id and data to paratree root