using System.Collections.Generic;
using System;
using System.Text;
using System.IO;

namespace PinyinModel
{
    class PinyinModel
    {
        public class Solution
        {
            public string sentence;
			public string[] pinyin;
            public double probability;
			
			public string getPinyinString()
			{
				StringBuilder buffer = new StringBuilder();
				foreach(string pinyin in this.pinyin)
				{
					buffer.Append(pinyin);
					buffer.Append(' ');
				}
				buffer.Remove(buffer.Length - 1, 1);
				return buffer.ToString();
			}
        }

        PinyinSyllable syllables;
        Lexicon dictionary;
        LanguageMode slm;
        SyllableGraph syllable_graph;
        LexiconGraph lexicon_graph;
        SLMGraph slm_graph;

        public void initializeSyllable()
        {
            this.syllables = new PinyinSyllable("syllable.bdt");
        }

        public void initializeLexicon()
        {
            if (this.syllables == null)
                this.initializeSyllable();
            this.dictionary = new Lexicon("lexicon.bdt", this.syllables);
        }

        public void initializeSLM()
        {
            if (this.dictionary == null)
                this.initializeLexicon();
            this.slm = new LanguageMode("slm.bdt", this.dictionary);
        }

        public void parsePinyinString(string pystring)
        {
            if (this.syllables == null)
                this.initializeSyllable();
            syllable_graph = new SyllableGraph(pystring, syllables);
        }

        public void makeLexiconGraph()
        {
            if (this.dictionary == null)
                this.initializeLexicon();
            if (this.syllable_graph == null)
                throw new Exception("InvalidSyllable");

            lexicon_graph = new LexiconGraph(
                syllable_graph.Count,
                syllable_graph.GetPinyinSequences(dictionary.MaxLength),
                dictionary
            );
        }

        public void makeSLMGraph(int solution_size)
        {
            if (this.slm == null)
                this.initializeSLM();
            if (lexicon_graph == null)
                this.makeLexiconGraph();
            slm_graph = new SLMGraph(lexicon_graph, slm, solution_size);
        }

        public Solution[] makeSentences()
        {
            if (slm_graph == null)
                throw new Exception("InvalidSLMGraph");
            return slm_graph.MakeSentence();
        }

        public void reset()
        {
            this.syllable_graph = null;
            this.slm_graph = null;
            this.lexicon_graph = null;
        }

        internal void output()
        {
            StringBuilder buffer = new StringBuilder();
            buffer.AppendLine("Syllable");
            buffer.Append(syllable_graph);
            buffer.AppendLine("Lexicon");
            buffer.Append(lexicon_graph);
            buffer.AppendLine("SLM");
            buffer.Append(slm_graph);

            StreamWriter writer = new StreamWriter("graph.txt");
            writer.Write(buffer.ToString());
            writer.Close();
        }
    }
}
