
var m = require('mithril');

// https://github.com/markdown-it/markdown-it
var markdown =  require('markdown-it')()
                  .use(require('markdown-it-footnote'));

var _dbs = require('./dbs');
var _Header = require('./header');
var _Footer = require('./footer');
var _Ui = require('./ui.js');

//     ____        __
//    / __ \____  / /_
//   / / / / __ \/ __/
//  / /_/ / /_/ / /_
// /_____/\____/\__/
var _Dot = {
  id:null,
  dottype:null,
  type:'',
  title:'',
  breadcrumb:'',
  text:'',
  summary:'',
  active:true,
  opened:0,
  nested:false,
  links:null,
  parents:[],
  lang:null,
  setupTitle(vn){
    this.title = vn.attrs.title;
    if(!this.title) this.title = this.type;

    if(this.title)
      this.title = markdown.renderInline(this.title);
  },
  setuptext(vn){
    // console.log('setuptext', vn);

    // construct text
    this.text = vn.attrs.text || '';
    this.rendered_text = markdown.render(this.text);

    if(this.dottype == "preface"){
      this.summary = this.rendered_text;
    }else{
      // construct summary
      // TODO: summary needs more work (strip tags, markdown render)
      // remove img
      this.summary = this.text.replace(/!\[[^\]]+\]\([^\)]+\)/g, "");
      // get portion of text
      // this.summary = this.summary.match('([^ ]*[ ]{0,1}){1,6}')[0];
      // https://stackoverflow.com/questions/5454235/shorten-string-without-cutting-words-in-javascript
      // this.summary = this.summary.replace(/^(.{18}[^\s]*).*/, "$1");
      this.summary = this.summary.substr(0, this.summary.lastIndexOf(' ', 30));
      // end underscores (italic) splited by summarizing
      this.summary = this.summary.trim().replace(/_([^_]+)$/g, "_$1_");
      // remove brackets (links) splited by summarizing
      this.summary = this.summary.replace(/\[([^\]]+)$/g, "$1");
      // render the markdown
      this.summary = markdown.renderInline(this.summary) + "&nbsp;…";
    }

  },
  oninit(vn){
    this.id = vn.attrs.id;
    this.type = vn.attrs.type;
    this.level = vn.attrs.level;
    this.dottype = vn.attrs.dottype;
    this.breadcrumb = vn.attrs.breadcrumb;
    // console.log(`${this.id} -> ${this.dottype}`);

    if(typeof vn.attrs.active !== 'undefined')
      this.active = vn.attrs.active;

    // links
    this.links = _dbs.data_strct[this.id];

    // parents memorize where do we come from to avoid duplicates and looping nav
    if(vn.attrs.parents){
      this.parents = this.parents.concat(vn.attrs.parents);
      // console.log('_Dot init '+this.id+' parents :',this.parents);
    }
    this.nested = this.parents.length ? true : false;
    // if(this.nested) console.log(`oninit ${this.id}`);

    this.lang = vn.attrs.lang;

    this.setupTitle(vn);
    this.setuptext(vn);
  },
  oncreate(vn){
    if(this.active){
      vn.dom.classList.remove('disabled');
    }else{
      vn.dom.classList.add('disabled');
    }
  },
  onbeforeupdate(vn){
    if(this.lang != vn.attrs.lang){
      this.lang = vn.attrs.lang;
      this.breadcrumb = vn.attrs.breadcrumb;
      this.type = vn.attrs.type;
      this.setuptext(vn);
      this.setupTitle(vn);
    }
  },
  onupdate(vn){
    // if(this.nested) console.log(`onupdate ${this.id}`);
    if(this.active){
      if (this.opened){
        vn.dom.classList.add('opened');
        if(this.links.to.length)
          vn.dom.classList.add('to-links');
        if(this.links.from.length)
          vn.dom.classList.add('from-links');
      }else{
        vn.dom.classList.remove('opened');
      }
    }
  },
  setupLinks(vn, c, links){
    return m('nav', {'class':`links ${c}`}, links.map(id => {
        // console.log(id);
        if(typeof _dbs.data_byid[this.lang][id] !== 'undefined'){
          var obj = _dbs.data_byid[this.lang][id];
          // console.log('link to : obj', obj);
          return m(_Dot, {
            "id":id,
            'title':obj.title,
            // TODO: translate breadcrumb
            'breadcrumb':obj.breadcrumb,
            'text':obj.text,
            'dottype':obj.dottype,
            'type':obj.type,
            // passe the memory of crossed dots plus the current one
            'parents':vn.state.parents.concat([vn.state.id]),
            // activate link only if not in parents (already went through it)
            'active':vn.state.parents.indexOf(id) == -1 ? true:false,
            // 'nested':true,
            'lang':this.lang,
          });
        }
      })
    );
  },
  viewOpenedContent(vn){
    return m('div', {
        'uid':this.id,
        'class':`dot ${this.dottype}${this.nested ? ' nested':''}`},
      [
        // links to
        this.links.to.length
          ? this.setupLinks(vn, 'to', this.links.to)
          : null, // if no links to, add nothing
        // close btn
        m('div', {
            'class':'close-link-btn',
            onclick(e){
              vn.state.opened = 0;
            }
          }//, m('span') // , m.trust("&#128473;")
        ),
        // Title
        m('span', {'class':'title'}, m.trust(this.nested || _dbs.active_type_filter ? this.breadcrumb : this.title)),
        // full text
        m('section', {
            'class':'text',
            onmouseover(e){
              e.preventDefault();
              if(e.target.nodeName == "A" ){
                let id = e.target.getAttribute("href");
                // add highlight class
                vn.dom.querySelector(`nav.links>div[uid="${id}"]`).classList.add('highlight');
              }else{
                // remove all hilight class
                for (let link of vn.dom.querySelectorAll('nav.links>div.dot')) {
                  link.classList.remove('highlight');
                }
              }
            },
            onclick(e){
              e.preventDefault();
              if(e.target.nodeName == "A" ){
                let id = e.target.getAttribute("href");
                vn.dom.querySelector(`nav.links>div[uid="${id}"]>.title`).click();
              }
            }
          }, m.trust(this.rendered_text)
        ),
        // links from
        this.links.from.length
          ? this.setupLinks(vn, 'from', this.links.from)
          : null, // if no links from, add nothing
      ]
    );
  },
  viewPreviewContent(vn){
    return m('div', {
        'uid':this.id,
        'class':`dot ${this.dottype}${this.nested ? ' nested':''}`
      },
      [
        // bullet
        m('div', {'class':'bullet'}, m('span', m.trust('&#9899;'))),
        m('span', {
          'class':'title',
          onclick(e){
            if(!vn.state.opened) vn.state.opened = 1;
          }
        }, m.trust(this.nested || _dbs.active_type_filter ? this.breadcrumb : this.title)),
        m('p', {
          'class':'summary',
          onclick(e){
            if(!vn.state.opened) vn.state.opened = 1;
          }
        }, m.trust(this.summary))
      ]
    );
  },
  view(vn){
    return this.active && vn.state.opened
      ? this.viewOpenedContent(vn)  // full view of dot with linked dots
      : this.viewPreviewContent(vn); // preview dot
  }
}

/*
full list of black dotlikes from unicode
● - &#9679; - Black Circle
⏺ - &#9210; - Black Circle for Record
⚫ - &#9899; - Medium Black Circle
⬤ - &#11044; - Black Large Circle
⧭ - &#10733; - Black Circle with Down Arrow
🞄 - &#128900; - Black Slightly Small Circle
• - &#8226; - Bullet
∙ - &#8729; - Bullet Operator
⋅ - &#8901; - Dot Operator
🌑 - &#127761; - New Moon Symbol
*/

//   _______   _ __   __
//  / ___/ /  (_) /__/ /
// / /__/ _ \/ / / _  /
// \___/_//_/_/_/\_,_/
var _Child = {
  // oninit(vn){},
  // onbeforeupdate(vn, old){},
  view(vn){
    return [
      !_dbs.active_type_filter || _dbs.active_type_filter == vn.attrs.dottype
        ? m(_Dot, vn.attrs)
        : null,
      // add children
      typeof vn.attrs.childs !== 'undefined'
        ? vn.attrs.childs.map(c => {
          c.lang = vn.attrs.lang;
          c.level = vn.attrs.level + 1;
          return m(_Child, c);
        })
        : null
    ];
  }
};

//     ______
//    / ____/___  ____  ____  ________
//   / __/ / __ \/ __ \/ __ \/ ___/ _ \
//  / /___/ / / / /_/ / / / / /__/  __/
// /_____/_/ /_/\____/_/ /_/\___/\___/
var _Enonce = {
  // oninit(vn){},
  // onbeforeupdate(vn, old) {},
  view(vn){
    vn.attrs.level = 0;
    return [
      !_dbs.active_type_filter || _dbs.active_type_filter == vn.attrs.dottype
      // create dot
        ? m(_Dot, vn.attrs)
        : null,
      // add children
      vn.attrs.childs.map(c => {
        c.lang = vn.attrs.lang;
        c.level = 1;
        return m(_Child, c);
      })
    ]
  }
}


//     ____             __
//    / __ \____ ______/ /_
//   / /_/ / __ `/ ___/ __/
//  / ____/ /_/ / /  / /_
// /_/    \__,_/_/   \__/
var _Part = {
  oninit(vn){
    this.id = vn.attrs.id;
    this.title = vn.attrs.title || "";
  },
  onbeforeupdate(vn, old){
    this.title = vn.attrs.title || "";
  },
  view(vn){
    return m("section", {
        'id'    :this.id,
        'class' :'part'
      },
      [
        // create title node
        m("h1", {'class':'part-title', 'part':this.id}, m.trust(markdown.renderInline(this.title))),
        // create text node
        vn.attrs.enonces.map(e => {
          // console.log(e.text);
          e.lang = vn.attrs.lang;
          switch (e.type) {
            case "title":
              // if(_dbs.active_type_filter){
              //   console.log('filter:', _dbs.active_type_filter, 'title:',e.title);
              // }
              // handle titles
              return !_dbs.active_type_filter
                ? m("h2", {'class':'title'}, m.trust(markdown.renderInline(e.title)))
                : null;
              break;
            case "filet":
              // handle filets
              return m("h4", {'class':'filet'}, m.trust(markdown.renderInline(e.title)));
              break;
            default:
              // or build structure
              return m(_Enonce, Object.assign({"partid":this.id},e));
          }
        })
      ]
    )
  }
}

//     ____      __
//    /  _/___  / /__________
//    / // __ \/ __/ ___/ __ \
//  _/ // / / / /_/ /  / /_/ /
// /___/_/ /_/\__/_/   \____/
var _Intro = {
  oninit(vn){
    console.log('_Intro : oninit : vn', vn);
    this.id = vn.attrs.id;
    this.text = vn.attrs.text || '';
  },
  onbeforeupdate(vn, old){
    this.id = vn.attrs.id;
    this.text = vn.attrs.text || '';
  },
  view(vn){
    return m("section", {'class':'intro'}, m("p",m.trust(markdown.renderInline(this.text))));
  }
}

//    ______                            __  _
//   / ____/___  ____  ____  ___  _____/ /_(_)___  ____  _____
//  / /   / __ \/ __ \/ __ \/ _ \/ ___/ __/ / __ \/ __ \/ ___/
// / /___/ /_/ / / / / / / /  __/ /__/ /_/ / /_/ / / / (__  )
// \____/\____/_/ /_/_/ /_/\___/\___/\__/_/\____/_/ /_/____/
module.exports = {
  oncreate(vn){
    document.body.classList.add('mode-connections');
    _Ui.init();
  },
  onbeforeupdate(vn, old){
    console.log('Connection, onbeforeupdate old',old, 'vn',vn);
  },
  view(vn){
    // console.log('_ModeConnections view', vn.attrs.lang);
    console.log('_dbs.active_type_filter : ', _dbs.active_type_filter);
    return m('main', {id:"content", 'class':'mode-connections'}, _dbs.data[vn.attrs.lang].map(p => {
        p.lang = vn.attrs.lang;
        if(p.id == 'intro'){
          return m(_Intro,p);
        }else{
          return m(_Part,p);
        }
      })
    );
  }
}
