/// <summary>
 /// Fires OnUpdate event if there are listeners.  This event
 /// is fired approx every 250 lines read in the file.
 /// </summary>
 /// <param name="updateArgs">CodeCounterUpdateEventArgs</param>
 private void FireOnUpdateEvent(CodeCounterUpdateEventArgs updateArgs)
 {
     if (null != OnUpdate)
     {
         OnUpdate(this, updateArgs);
     }
 }
 /// <summary>
 /// Fires the OnStartEvent if there are listeners.  This 
 /// event is fired once per file.
 /// </summary>
 /// <param name="startArgs">CodeCounterUpdateEventArgs</param>
 private void FireOnStartEvent(CodeCounterUpdateEventArgs startArgs)
 {
     if (null != OnStart)
     {
         OnStart(this, startArgs);
     }
 }
 /// <summary>
 /// Fires the OnStartEvent if there are listeners.  This
 /// event is fired once per file.
 /// </summary>
 /// <param name="startArgs">CodeCounterUpdateEventArgs</param>
 private void FireOnStartEvent(CodeCounterUpdateEventArgs startArgs)
 {
     if (null != OnStart)
     {
         OnStart(this, startArgs);
     }
 }
 /// <summary>
 /// Updates from the code counter as it evaluates a file
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="erasureArgs">CodeCounterUpdateEventArgs</param>
 private void OnCodeCountingUpdate(object sender, CodeCounterUpdateEventArgs erasureArgs)
 {
     lock (_lockObject)
     {
         try
         {
             // move cursor back to starting position, ignoring if we muck up
             DrawSpinner();
         }
         catch (Exception ex)
         {
             System.Diagnostics.Debug.WriteLine(ex.Message);
         }
     }
 }
        /// <summary>
        /// Indicates a file has been found that matches our criteria for counting the lines
        /// of code in the file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="startArgs">CodeCounterUpdateEventArgs</param>
        private void OnCodeCountingStart(object sender, CodeCounterUpdateEventArgs startArgs)
        {
            try
            {
                System.Diagnostics.Debug.Assert(0 == _erasableTextLengh);

                if (0 != _lastDirectoryProcessed.CompareTo(startArgs.FileInfo.DirectoryName))
                {
                    _lastDirectoryProcessed = startArgs.FileInfo.DirectoryName;
                    string directory = string.Format("{0}:", _lastDirectoryProcessed);
                    Console.WriteLine(directory);
                }

                _spinnerPosition   = 0;
                _erasableTextLengh = 0;
                string fileName = string.Format("\t{0}: ", startArgs.FileInfo.Name);
                Console.Write(fileName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }
        /// <summary>
        /// The heart of the counting of lines
        /// </summary>
        public void Count()
        {
            // nothing to process if we have no file name
            if (null == _fileInfo)
            {
                return;
            }

            // ensures member data is reset to default
            InitializeCounters();
            long linesRead = 0L;

            // event arg initialization
            CodeCounterFinishedEventArgs finishedArgs   = new CodeCounterFinishedEventArgs(_fileInfo, CodeCounterFunctionTypes.Error);
            CodeCounterUpdateEventArgs   startArgs      = new CodeCounterUpdateEventArgs(_fileInfo, CodeCounterFunctionTypes.ProcessingFiles);
            CodeCounterUpdateEventArgs   updateEventArg = new CodeCounterUpdateEventArgs(_fileInfo, CodeCounterFunctionTypes.ProcessingFiles);

            try
            {
                // let console know we found a file
                FireOnStartEvent(startArgs);

                // find the appropriate handler for the type
                ICodeCounterLogic processor    = GetFileProcessor(_fileInfo);
                bool _processorDeterminesEmpty = processor.EngineCanDetermineBlankLines();

                // allow the ICodeCounterLogic implementation a chance to
                // do something with the file
                processor.PrefileProcessing(_fileInfo.FullName);

                // now we can read through each line and count what it contains
                using (TextReader fileReader = _fileInfo.OpenText())
                {
                    string line = "";

                    while (null != (line = fileReader.ReadLine()))
                    {
                        linesRead++;

                        long mod = (linesRead % 250L);

                        if (0L == mod)
                        {
                            updateEventArg.Lines = linesRead;
                            FireOnUpdateEvent(updateEventArg);
                        }

                        string trimmed = line.Trim();

                        // when the processor does not know or care how empty lines are determined
                        // we will do it by testing for null or empty line.
                        if ((true == _processorDeterminesEmpty) && (true == string.IsNullOrEmpty(trimmed)))
                        {
                            continue;
                        }

                        // now we are ready to let the implemention decide what the line is
                        CodeCounterLineType lineType = processor.LineType(trimmed);

                        switch (lineType)
                        {
                        case CodeCounterLineType.Statement:
                        case CodeCounterLineType.Code:
                            _codeLines++;
                            break;

                        case CodeCounterLineType.StatementAndComment:
                        case CodeCounterLineType.CodeAndComment:
                            _codeLines++;
                            _commentLines++;
                            break;

                        case CodeCounterLineType.CommentOnly:
                            _commentLines++;
                            break;

                        default:
                            break;
                        }

                        if (CodeCounterLineType.EmptyLine != lineType)
                        {
                            _totalLines++;
                        }
                    }

                    // yay we are done
                    fileReader.Close();

                    // allow the counter implemenation any final moments
                    processor.PostfileProcessing(_fileInfo.FullName);

                    finishedArgs.Function = CodeCounterFunctionTypes.Summarizing;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                finishedArgs.Function       = CodeCounterFunctionTypes.Error;
                finishedArgs.AdditionalData = ex;
            }
            finally
            {
                finishedArgs.FileInfo       = _fileInfo;
                finishedArgs.CodeLines      = _codeLines;
                finishedArgs.CommentLines   = _commentLines;
                finishedArgs.StatementLines = _statementLines;
                finishedArgs.Lines          = _totalLines;
                _fileInfo = null;

                FireOnFinishedEvent(finishedArgs);
            }
        }
        /// <summary>
        /// Indicates a file has been found that matches our criteria for counting the lines
        /// of code in the file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="startArgs">CodeCounterUpdateEventArgs</param>
        private void OnCodeCountingStart(object sender, CodeCounterUpdateEventArgs startArgs)
        {
            try
            {
                System.Diagnostics.Debug.Assert(0 == _erasableTextLengh);

                if (0 != _lastDirectoryProcessed.CompareTo(startArgs.FileInfo.DirectoryName))
                {
                    _lastDirectoryProcessed = startArgs.FileInfo.DirectoryName;
                    string directory = string.Format("{0}:", _lastDirectoryProcessed);
                    Console.WriteLine(directory);
                }

                _spinnerPosition = 0;
                _erasableTextLengh = 0;
                string fileName = string.Format("\t{0}: ", startArgs.FileInfo.Name);
                Console.Write(fileName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }
 /// <summary>
 /// Updates from the code counter as it evaluates a file
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="erasureArgs">CodeCounterUpdateEventArgs</param>
 private void OnCodeCountingUpdate(object sender, CodeCounterUpdateEventArgs erasureArgs)
 {
     lock (_lockObject)
     {
         try
         {
             // move cursor back to starting position, ignoring if we muck up
             DrawSpinner();
         }
         catch (Exception ex)
         {
             System.Diagnostics.Debug.WriteLine(ex.Message);
         }
     }
 }
 /// <summary>
 /// Fires OnUpdate event if there are listeners.  This event
 /// is fired approx every 250 lines read in the file.
 /// </summary>
 /// <param name="updateArgs">CodeCounterUpdateEventArgs</param>
 private void FireOnUpdateEvent(CodeCounterUpdateEventArgs updateArgs)
 {
     if (null != OnUpdate)
         OnUpdate(this, updateArgs);
 }
        /// <summary>
        /// The heart of the counting of lines
        /// </summary>
        public void Count()
        {
            // nothing to process if we have no file name
            if (null == _fileInfo)
                return;

            // ensures member data is reset to default
            InitializeCounters();
            long linesRead = 0L;

            // event arg initialization
            CodeCounterFinishedEventArgs finishedArgs = new CodeCounterFinishedEventArgs(_fileInfo, CodeCounterFunctionTypes.Error);
            CodeCounterUpdateEventArgs startArgs = new CodeCounterUpdateEventArgs(_fileInfo, CodeCounterFunctionTypes.ProcessingFiles);
            CodeCounterUpdateEventArgs updateEventArg = new CodeCounterUpdateEventArgs(_fileInfo, CodeCounterFunctionTypes.ProcessingFiles);

            try
            {
                // let console know we found a file
                FireOnStartEvent(startArgs);

                // find the appropriate handler for the type
                ICodeCounterLogic processor = GetFileProcessor(_fileInfo);
                bool _processorDeterminesEmpty = processor.EngineCanDetermineBlankLines();

                // allow the ICodeCounterLogic implementation a chance to 
                // do something with the file
                processor.PrefileProcessing(_fileInfo.FullName);

                // now we can read through each line and count what it contains
                using (TextReader fileReader = _fileInfo.OpenText())
                {
                    string line = "";

                    while (null != (line = fileReader.ReadLine()))
                    {
                        linesRead++;

                        long mod = (linesRead % 250L);

                        if (0L == mod)
                        {
                            updateEventArg.Lines = linesRead;
                            FireOnUpdateEvent(updateEventArg);
                        }

                        string trimmed = line.Trim();

                        // when the processor does not know or care how empty lines are determined
                        // we will do it by testing for null or empty line.  
                        if ((true == _processorDeterminesEmpty) && (true == string.IsNullOrEmpty(trimmed)))
                            continue;

                        // now we are ready to let the implemention decide what the line is
                        CodeCounterLineType lineType = processor.LineType(trimmed);

                        switch (lineType)
                        {
                            case CodeCounterLineType.Statement:
                            case CodeCounterLineType.Code:
                                _codeLines++;
                                break;
                            case CodeCounterLineType.StatementAndComment:
                            case CodeCounterLineType.CodeAndComment:
                                _codeLines++;
                                _commentLines++;
                                break;
                            case CodeCounterLineType.CommentOnly:
                                _commentLines++;
                                break;
                            default:
                                break;
                        }

                        if (CodeCounterLineType.EmptyLine != lineType)
                            _totalLines++;
                    }

                    // yay we are done
                    fileReader.Close();

                    // allow the counter implemenation any final moments
                    processor.PostfileProcessing(_fileInfo.FullName);

                    finishedArgs.Function = CodeCounterFunctionTypes.Summarizing;
                }                
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                finishedArgs.Function = CodeCounterFunctionTypes.Error;
                finishedArgs.AdditionalData = ex;
            }
            finally
            {
                finishedArgs.FileInfo = _fileInfo;
                finishedArgs.CodeLines = _codeLines;
                finishedArgs.CommentLines = _commentLines;
                finishedArgs.StatementLines = _statementLines;
                finishedArgs.Lines = _totalLines;
                _fileInfo = null;

                FireOnFinishedEvent(finishedArgs);
            }
        }