using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Data;
using System.Windows;
using VBNET = Microsoft.VisualBasic;
using gmRTL.Core;
using Microsoft.VisualBasic.CompilerServices;
using System.Linq;
using System.Collections.Generic;

namespace ScanToolLib
{
   public class clsVBPCntReporter
   {
      //  clsVBPCntReporter: Report Count of Line types for all modules referenced by a VBP file

      public class statusEventArgs : System.EventArgs
      {
         public string msg;
         public statusEventArgs(string msg)
         {
            this.msg = msg;
         }
      }
      public delegate void statusEventHandler(object sender,statusEventArgs e);
      public event System.EventHandler<statusEventArgs> status_Event;
      protected virtual void Onstatus_Event(string msg)
      {
         statusEventArgs e;
         if(status_Event != null)
         {
            e = new statusEventArgs(msg);
            status_Event?.Invoke(this,e);
         }
      }
      public string header()
      {
         return "VBPPATH" + "\t" + "VBPNAME" + "\t" + "MODNAME" + "\t" + "MODTIME" + "\t" + "MODTYPE" + "\t" + "COD" + "\t" + "GUI" + "\t" + "REF" + "\t" + "CMN" + "\t" + "BLN";
      }
      public void processFile(System.IO.FileInfo fil,System.IO.StreamWriter rpt)
      {
         const string FUNC_NAME = "processFile";
         System.IO.StreamReader txtfil = null;
         try
         {
            gmRTL.Core.GlobalException.Clear();

            int lCOD = 0;
            int lREF = 0;

            string filpath = "";
            filpath = fil.Directory.FullName;
            string filname = "";
            filname = fil.Name;
            string modtype = "";
            string modname = "";
            string modpath = "";


            txtfil = modScanToolLib.openInputText(fil.FullName);

            string s = "";
            s = txtfil.ReadToEnd();

            string[] arr = Array.Empty<string>();
            arr = s.Split("\r\n");

            lCOD = arr.GetUpperBound(0);

            foreach(string v in arr)
            {

               modtype = "";
               string sLine = "";
               sLine = v.LCase();

               if (sLine.Like("form=*.frm") || sLine.Like("class=*.cls") || sLine.Like("module=*.bas") || sLine.Like("usercontrol=*.ctl") || sLine.Like("propertypage=*.pag"))
               {
                  // ----------------------------------------------------
                  //  parse the reference for name path etc.
                  // ----------------------------------------------------

                  sLine = v;

                  int j = 0;
                  int i = 0;

                  i = sLine.InStr("=",1,StringComparison.CurrentCulture) + 1;

                  modtype = sLine.Left((i - 2));

                  sLine = (sLine.Mid(i)).TrimB();     //  object name; path

                  j = sLine.InStrRev(";",-1,StringComparison.CurrentCulture);

                  if (j == 0)
                  {
                     j = 1;
                  }
                  else
                  {
                     j = j + 1;
                  }

                  sLine = (sLine.Mid(j)).TrimB();     //  object path

                  j = sLine.InStrRev("\\",-1,StringComparison.CurrentCulture);

                  if (j == 0)
                  {
                     j = 1;
                  }
                  else
                  {
                     j = j + 1;
                  }

                  modname = (sLine.Mid(j)).TrimB();     //  file name

                  if (j == 1)
                  {
                     modpath = filpath + "\\" + modname;
                  }
                  else
                  {
                     modpath = sLine;
                  }

                  // ----------------------------------------------------
                  //  open file and count its lines
                  // ----------------------------------------------------

                  countLines(rpt,filpath,filname,modpath,modname,modtype);

               }
               else
               {
                       //  a project directive

                  if (v.Left(7) == "Object=" || v.Left(10) == "Reference=")
                  {
                     lREF = lREF + 1;
                  }
               }

            }

            // ----------------------------------------------------
            //  report totals for project
            // ----------------------------------------------------

            modScanToolLib.writeRpt(rpt,filpath + "\t" + fil.Name + "\t" + fil.Name + "\t" + fil.LastWriteTime.ToStr() + "\t" + "Project" + "\t" + lCOD + "\t" + 0 + "\t" + lREF + "\t" + 0 + "\t" + 0 + "\r\n");

         }
         catch(System.Exception exc)
         {
            gmRTL.Core.GlobalException.Initialize(exc);
         }

         if (!(txtfil == null))
         {
            txtfil.Close();
         }
         txtfil = null;

         if (gmRTL.Core.GlobalException.Instance.Number != 0)
         {
            gmRTL.Core.ErrorHandling.RaiseGlobalException(gmRTL.Core.GlobalException.Instance.Number,String.Empty,this.GetTypeName() + "::" + FUNC_NAME + " " + "\r\n" + "[" + fil.FullName + "]" + "\r\n" + gmRTL.Core.GlobalException.Instance.Description);
         }

      }
      private void countLines(System.IO.StreamWriter rpt,string vbppath,string vbpname,string modpath,string modname,string modtype)
      {
         const string FUNC_NAME = "countLines";
         int lCMN = 0;
         int lBLN = 0;
         int lCOD = 0;
         int lGUI = 0;
         int lREF = 0;
         System.IO.StreamReader txtfil = null;
         System.IO.FileInfo fil = null;
         try
         {
            gmRTL.Core.GlobalException.Clear();



            // ----------------------------------------------------
            //  open the module
            // ----------------------------------------------------

            txtfil = modScanToolLib.openInputText(modpath);

            // ----------------------------------------------------
            //  parse the module into an array of lines
            // ----------------------------------------------------

            string s = "";
            s = txtfil.ReadToEnd();

            string[] arr = Array.Empty<string>();
            arr = s.Split("\r\n");

            // ----------------------------------------------------
            //  default the line type for forms/ctls to GUI since
            //  the GUI spec is always at the top of the form/ctl.
            // ----------------------------------------------------

            string linetype = "";

            if (modtype == "Form" || modtype == "UserControl")
            {
               linetype = "GUI";
            }
            else
            {
               linetype = "COD";
            }

            // ----------------------------------------------------
            //  get modified date
            // ----------------------------------------------------

            DateTime LastModDate = DateTime.MinValue;
            fil = new System.IO.FileInfo(modpath);
            LastModDate = fil.LastWriteTime;

            // ----------------------------------------------------
            //  process each line
            // ----------------------------------------------------

            int l = 0;
            l = 1;

            foreach(string v in arr)
            {

               string sLine = "";
               sLine = v.ReplaceStr("\t","    ",1,-1,StringComparison.CurrentCulture);

               string trimmedLine = "";
               trimmedLine = sLine.TrimB();

               if (trimmedLine.Left(1) == "'")
               {
                  lCMN = lCMN + 1;
               }
               else if (trimmedLine.Len() == 0)
               {
                  lBLN = lBLN + 1;
               }
               else if (trimmedLine.Left(9) == "Object = ")
               {
                  lREF = lREF + 1;
               }
               else
               {
                  if (linetype == "GUI")
                  {
                     lGUI = lGUI + 1;
                     if (sLine == "End")
                     {
                        linetype = "COD";
                     }
                  }
                  else
                  {
                     lCOD = lCOD + 1;
                  }
               }

            }

            modScanToolLib.writeRpt(rpt,vbppath + "\t" + vbpname + "\t" + modname + "\t" + LastModDate.ToStr() + "\t" + modtype + "\t" + lCOD + "\t" + lGUI + "\t" + lREF + "\t" + lCMN + "\t" + lBLN + "\r\n");

         }
         catch(System.Exception exc)
         {
            gmRTL.Core.GlobalException.Initialize(exc);
         }

         if (!(txtfil == null))
         {
            txtfil.Close();
         }
         fil = null;
         txtfil = null;

         if (gmRTL.Core.GlobalException.Instance.Number != 0)
         {
            modScanToolLib.writeRpt(rpt,vbppath + "\t" + vbpname + "\t" + modname + "\t" + DateTime.Now.ToStr() + "\t" + modpath + ":" + gmRTL.Core.GlobalException.Instance.Description + "\t" + lCOD + "\t" + lGUI + "\t" + lREF + "\t" + lCMN + "\t" + lBLN + "\r\n");
         }

      }
   }
}
