context: //
  // DO NOT REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  //
  // @Authors:
  //       timop
  //
  // Copyright 2004-2012 by OM International
  //
  // This file is part of OpenPetra.org.
  //
  // OpenPetra.org is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  //
  // OpenPetra.org is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with OpenPetra.org.  If not, see <http://www.gnu.org/licenses/>.
  //
  using System;
  using Ict.Common.IO;
  using System.Xml;
  using System.Collections.Generic;
  using Ict.Common;
  using System.Globalization;
  
  namespace Ict.Petra.Server.MReporting
  {
      /// <summary>
      /// a parser for the XML file that defines a report
      /// </summary>
      public class TReportParser : TXMLParser
      {
          private TReportStore myStore;
  
          /// <summary>the currently processed reportId</summary>
          private string reportId;
  
          /// <summary>the currently processed report</summary>
          private TReportDefinition report;
  
          /// <summary>
          /// constructor
          /// </summary>
          /// <param name="filename"></param>
          /// <param name="withValidation"></param>
          public TReportParser(string filename, Boolean withValidation) :
              base(filename, withValidation)
          {
          }
  
          /// <summary>
          /// constructor
          /// </summary>
          /// <param name="filename"></param>
          public TReportParser(string filename) : base(filename)
          {
          }
  
          /// <summary>
          /// constructor
          /// </summary>
          /// <param name="AReuseParser"></param>
          public TReportParser(TXMLParser AReuseParser) : base(AReuseParser)
          {
          }
  
          /// <summary>
          /// Knows how to parse all the entities in the document.
          /// It reads a group of entities.
          /// </summary>
          /// <param name="cur2">The current node in the document that should be parsed</param>
          /// <param name="groupId">The id of the previous group System.Object of this type</param>
          /// <param name="entity">The name of the elements that make up the group</param>
          /// <param name="newcur">After parsing, the then current node is returned in this parameter</param>
          /// <returns>The group of elements, or nil</returns>
          protected Object ParseGroup(XmlNode cur2, ref int groupId, string entity, out XmlNode newcur)
          {
              Object ReturnValue;
              int order;
              int currentGroup;
              XmlNode cur;
  
              newcur = cur2;
              cur = NextNotBlank(cur2);
              ReturnValue = null;
  
              if ((cur == null) || (cur.Name != entity))
              {
                  return null;
              }
  
              groupId++;
              currentGroup = groupId;
              order = 0;
  
              while ((cur != null) && (cur.Name == entity))
              {
                  if (entity == "value")
                  {
                      ReturnValue = ParseValueGroup(cur, (List <TRptValue> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "calculation")
                  {
                      ReturnValue = ParseCalculationGroup(cur, (List <TRptCalculation> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "field")
                  {
                      ReturnValue = ParseFieldGroup(cur, (List <TRptField> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "fielddetail")
                  {
                      ReturnValue = ParseFieldDetailGroup(cur, (List <TRptFieldDetail> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "level")
                  {
                      ReturnValue = ParseLevelGroup(cur, (List <TRptLevel> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "lowerLevelReport")
                  {
                      ReturnValue = ParseLowerLevelGroup(cur, (List <TRptLowerLevel> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "switch")
                  {
                      ReturnValue = ParseSwitchGroup(cur, (List <TRptSwitch> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "if")
                  {
                      ReturnValue = ParseIfGroup(cur, (List <TRptSwitch> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "case")
                  {
                      ReturnValue = ParseCaseGroup(cur, (List <TRptCase> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "queryDetail")
                  {
                      ReturnValue = ParseQueryGroup(cur, (List <TRptQuery> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "parameter")
                  {
                      ReturnValue = ParseParameterGroup(cur, (List <TRptParameter> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "detailreport")
                  {
                      ReturnValue = ParseDetailReportGroup(cur, (List <TRptDetailReport> )ReturnValue, currentGroup, order);
                  }
                  else if (entity == "report")
                  {
                      ParseReport(cur);
                  }
                  else if (entity == "reportparameter")
                  {
                  }
                  // do nothing
                  else
                  {
                      TLogging.Log("missing something? group " + entity);
                  }
  
                  order++;
                  cur = NextNotBlank(cur.NextSibling);
              }
  
              newcur = cur;
              return ReturnValue;
          }
  
          /// <summary>
          /// Knows how to parse all the entities in the document.
          /// It reads a group of entities.
          /// </summary>
          /// <param name="cur2">The current node in the document that should be parsed</param>
          /// <param name="groupId">The id of the previous group System.Object of this type</param>
          /// <param name="entity">The name of the elements that make up the group</param>
          /// <returns>The group of elements, or nil
          /// </returns>
          protected Object ParseGroup(XmlNode cur2, ref int groupId, string entity)
          {
              XmlNode newNode;
  
              return ParseGroup(cur2, ref groupId, entity, out newNode);
          }
  
          /// <summary>
          /// If the current node holds a entity of type groupentity,
          /// then the contained elements of type entity are parsed.
          /// </summary>
          /// <param name="groupentity">The name of the entity that holds the group of elements</param>
          /// <param name="cur">The current node</param>
          /// <param name="groupId">The current id for the group.
          /// This number will be increased and then used to create the new group.</param>
          /// <param name="entity">The name of the entitiy that represents the elements</param>
          /// <returns>The group of elements, or nil if node does not point to that group entity or the group entity is empty.
          /// </returns>
          protected Object Parse(string groupentity, ref XmlNode cur, ref int groupId, string entity)
          {
              Object ReturnValue;
  
              ReturnValue = null;
  
              if (cur.Name == groupentity)
              {
                  cur = NextNotBlank(cur);
                  ReturnValue = ParseGroup(cur.FirstChild, ref groupId, entity);
                  cur = GetNextEntity(cur);
              }
  
              return ReturnValue;
          }
  
          /// <summary>
          /// Knows how to parse all the entities in the document.
          /// Reads one or more entities of the same type.
          /// </summary>
          /// <param name="cur">The current node</param>
          /// <param name="groupId">The id of the current group that the elements will belong to</param>
          /// <param name="entity">The name of the entity that should be read</param>
          /// <returns>the last of the read entities
          /// </returns>
          protected Object Parse(XmlNode cur, ref int groupId, string entity)
          {
              Object ReturnValue;
              int order;
  
              cur = NextNotBlank(cur);
              ReturnValue = null;
  
              if ((cur == null) || (cur.Name.ToLower() != entity.ToLower()))
              {
                  return null;
              }
  
              groupId++;
              order = 0;
  
              while ((cur != null) && (cur.Name.ToLower() == entity.ToLower()))
              {
                  if (entity == "detail")
                  {
                      ReturnValue = ParseDetail(cur, order);
                  }
                  else
                  {
                      if (entity == "default")
                      {
                          ReturnValue = ParseCase(cur, order);
                      }
                      else
                      {
                          if (entity == "case")
                          {
                              ReturnValue = ParseCase(cur, order);
                          }
                          else
                          {
                              if (entity == "if")
                              {
                                  ReturnValue = ParseCase(cur, order);
                              }
                              else
                              {
                                  if (entity == "switch")
                                  {
                                      ReturnValue = ParseSwitch(cur, order);
                                  }
                                  else
                                  {
                                      if (entity == "lowerlevelreport")
                                      {
                                          ReturnValue = ParseLowerLevel(cur, order);
                                      }
                                      else
                                      {
                                          if (entity == "report")
                                          {
                                              ReturnValue = ParseReport(cur);
                                          }
                                          else
                                          {
                                              if (entity == "description")
                                              {
                                              }
                                              // do nothing
                                              else
                                              {
                                                  TLogging.Log("missing something? single " + entity);
                                              }
                                          }
                                      }
                                  }
                              }
                          }
                      }
                  }
  
                  order++;
                  cur = NextNotBlank(cur.NextSibling);
              }
  
              return ReturnValue;
          }
  
          /// <summary>
          /// main function
          /// </summary>
          /// <param name="myStore"></param>
          /// <returns></returns>
          public Boolean ParseDocument(ref TReportStore myStore)
          {
              Boolean ReturnValue;
              int dummy;
              XmlNode startNode;
  
              this.myStore = myStore;
              dummy = 0;
              ReturnValue = false;
              startNode = myDoc.DocumentElement;
  
              if (startNode.Name.ToLower() == "reports")
              {
                  ReturnValue = (ParseGroup(startNode.FirstChild, ref dummy, "report") != null);
              }
  
              return ReturnValue;
          }
  
          /// <summary>
          /// specific for reports
          /// </summary>
          /// <returns>void</returns>
          protected Object ParseReport(XmlNode cur2)
          {
              XmlNode cur;
              int dummy = -1;
              Object rg;
  
              cur = cur2;
              reportId = GetAttribute(cur, "id");
              report = myStore.Add(reportId);
              cur = NextNotBlank(cur.FirstChild);
  
gt:             Parse(cur, ref dummy, "description");