context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.IO;
  using System.Diagnostics;
  using System.Runtime.Serialization;
  using System.Runtime.Serialization.Formatters.Binary;
  using System.Xml.Serialization;
  using System.Text.RegularExpressions;
  using System.Data;
  using uQlustCore.Interface;
  using uQlustCore.Profiles;
  
  namespace uQlustCore
  {
  
      public enum wOpertion
      {
          SUM,
          MULT
      };
      public enum profileType
      {
          INTERNAL,
          EXTERNAL
      };
      [Serializable]
      public class ProfileTree:IProgressBar
      {
          string defaultProfile="default.profiles";
          public string listFile;
          Settings set = new Settings();
          public SerializableDictionary<string, profileNode> masterNode = new SerializableDictionary<string, profileNode>();
          public Dictionary<string,Dictionary<string, protInfo>> profiles = null;
          public Dictionary<string, List<byte>> protCombineStates = null;
          Dictionary<string, byte> protCombineCoding = new Dictionary<string, byte>();
          InternalProfilesManager mgr;
          IProgressBar progressObject = null;
          List<double> profilesProgress = null;
          int profilesNum = 0;
          int ttt;
          public ProfileTree()//(string profileFile)
          {
              mgr = new InternalProfilesManager();
              progressObject = mgr;
              set.Load();
          }
          public double ProgressUpdate()
          {
              double sum = 0;
              if (profilesProgress == null)
                  return 0;
  
              foreach (var item in profilesProgress)
              {
                  sum += item;
              }
  
              sum /= profilesNum*2;
  
              if(progressObject!=null)
                  sum=sum+progressObject.ProgressUpdate()/2;
  
  
              if (sum > 0)
                  ttt = 1;
  
              return sum;
          }
          public Exception GetException()
          {
              return null;
          }
          public List<INPUTMODE> GetModes()
          {
              Dictionary<INPUTMODE,int> dic=new Dictionary<INPUTMODE,int>();
              List<INPUTMODE> modes=new List<INPUTMODE>();
  
              foreach(var item in masterNode)
              {
  
                  profileNode n = InternalProfilesManager.GetNode(item.Value.internalName);
                  Type t = Type.GetType(InternalProfilesManager.internalList[n]);
                  InternalProfileBase c = Activator.CreateInstance(t) as InternalProfileBase;
                  foreach (var it in c.destination)
                      if (!dic.ContainsKey(it))
                          dic.Add(it, 1);
                      else
                          dic[it]++;
                              
              }
              foreach(var item in dic)
              {
                  if (item.Value == masterNode.Keys.Count)
                      modes.Add(item.Key);
              }
              return modes;
          }
          public void ClearTree()
          {
              if(masterNode!=null)
                  masterNode.Clear();
              if(profiles!=null)
                  profiles.Clear();
              if(protCombineStates!=null)
                  protCombineStates.Clear();
              if(protCombineCoding!=null)
                  protCombineCoding.Clear();
          }
          public List<KeyValuePair<string, DataTable>> GetResults()
          {
              return null;
          }
  
          public void AdddNode(string Path,profileNode newNode)
          {
              profileNode aux;
  
              if (Path==null || Path.Length == 0 || Path == "/")
              {
                  masterNode.Add(newNode.profName,newNode);
                  return;
              }
  
              aux = FindNode(Path);
              if (aux != null && !aux.childrens.ContainsKey(newNode.profName))                
                  aux.childrens.Add(newNode.profName, newNode);
              else
                  throw new Exception("New node cannot be added, wrong Path!");
  
          }
          public void RemoveOutFiles()
          {
              Queue<profileNode> nodeList = new Queue<profileNode>();
              profileNode aux;
  
              foreach (var item in masterNode.Values)
                      nodeList.Enqueue(item);
  
              while(nodeList.Count>0)
              {
                  aux = nodeList.Dequeue();
  
                  if (File.Exists(aux.OutFileName) && (!aux.OutFileName.Contains("dssp")))
                  {
                      if(aux.removeOutFile)
                          File.Delete(aux.OutFileName);
                  }
  
                  foreach (var item in aux.childrens.Values)
                              nodeList.Enqueue(item);
              }
              
          
  
          }
          public Dictionary<byte, Dictionary<byte, double>> GenerateWeights(wOpertion weightsOperation)
          {
              List<profileNode> active = GetActiveLeaves();
              Dictionary<string,int> dic = new Dictionary<string,int>();
              List<List<string>> item1 = new List<List<string>>();
              List<string> item2;
              Dictionary<byte, Dictionary<byte, double>> weights = new Dictionary<byte, Dictionary<byte, double>>();
              List <profileNode> activeNodes=new List<profileNode>();
  
              for (int i = 0; i < active.Count; i++)
              {
                  dic.Clear();
                  foreach (var itemK in active[i].profWeights.Keys)
                  {
                      if (!dic.ContainsKey(itemK))
                          dic.Add(itemK, 0);
                      foreach(var itemK1 in active[i].profWeights[itemK].Keys)
                          if (!dic.ContainsKey(itemK1))
                              dic.Add(itemK1, 0);
                  }
  
                  List<string> aux = new List<string>(dic.Keys);
                  item1.Add(aux);                
              }
              item2 = new List<string>(item1[0]); ;
              for (int i = 1; i < item1.Count; i++)
              {
                  List<string> newList = new List<string>();
                  for (int k = 0; k < item2.Count; k++)
                  {
                      string lan = item2[k];
                      for (int j = 0; j < item1[i].Count; j++)
                      {
                          lan = item2[k]+"-" + item1[i][j];
                          newList.Add(lan);
                      }
                  }
                  item2 = new List<string>(newList);
              }
  
              for (int i = 0; i < item2.Count; i++)
              {
                  string[] aux1 = item2[i].Split('-');
                  for (int j = 0; j < item2.Count; j++)
                  {
                      string[] aux2 = item2[j].Split('-');
                      for (int k = 0; k < aux1.Length; k++)
                      {
                          double wValue=0;
                          switch (weightsOperation)
                          {
                              case wOpertion.MULT:
                                  wValue = 1;
                                  break;
                              case wOpertion.SUM:
                                  wValue = 0;
                                  break;
                          }
                          for (int n = 0; n < active.Count; n++)
                          {
                              if (active[n].profWeights.ContainsKey(aux1[n]))
                                  switch (weightsOperation)
                                  {
                                      case wOpertion.MULT:
                                          if (active[n].profWeights[aux1[n]].ContainsKey(aux2[n]))
                                              wValue *= active[n].profWeights[aux1[n]][aux2[n]];
                                          else
                                              wValue = 0;
                                          break;
                                      case wOpertion.SUM:
                                          if (active[n].profWeights[aux1[n]].ContainsKey(aux2[n]))
                                              wValue += active[n].profWeights[aux1[n]][aux2[n]];
                                          break;
                                  }   
  
                          }
                          if (wValue > 0)
                          {
                              
                              string[] taux1 =new string [aux1.Length];
                              string[] taux2 =new string [aux2.Length];
                              for (int n = 0; n < aux1.Length; n++)
                              {
                                   taux1[n]= active[n].GetCodedState(aux1[n]).ToString();
                                   taux2[n] = active[n].GetCodedState(aux2[n]).ToString();
                                                          }
                              if (!protCombineCoding.ContainsKey(String.Join("", taux1)) || !protCombineCoding.ContainsKey(String.Join("", taux2)))
                                  continue;
                              byte k1=protCombineCoding[String.Join("",taux1)];
                              byte k2=protCombineCoding[String.Join("",taux2)];
                              if (!weights.ContainsKey(k1))
                              {
                                  Dictionary<byte, double> sAux = new SerializableDictionary<byte, double>();
                                  sAux.Add(k2, wValue);
                                  weights.Add(k1, sAux);
                              }
                              else
                              {
                                  Dictionary<byte, double> sAux = weights[k1];
                                  if (!sAux.ContainsKey(k2))
                                      sAux.Add(k2, wValue);
                              }
                          }
                      }
                  }
              }
              return weights;
          }
          private string ParentPath(string path)
          {
              string[] tmp = path.Split('/');
              path = String.Join("/", tmp, 0, tmp.Length - 1);
              if (path.Length == 0)
  
gt:                 path = "/";