/// <summary>
        /// begin new section 'data row' in current report
        /// </summary>
        /// <param name="id">row id</param>
        public void BeginDataRow(int id)
        {
            Indent++;

            SourceLine line = new SourceLine();
            for (int i = 0; i < Indent; i++)
                line.Columns.Add(string.Empty);

            line.Columns.Add(Constants.ReportText.BeginDataRow);
            line.Columns.Add(id.ToString());

            Lines.Add(line);
        }
        /// <summary>
        /// parse the source file
        /// </summary>
        /// <param name="path">the file path</param>
        /// <returns>return true if parse successfully</returns>
        private bool Parse(string path)
        {
            try
            {
                CompoundDocument doc = CompoundDocument.Load(path);
                if (doc == null)
                    throw new InvalidOperationException(Constants.Messages.Error_ExcelFileNotFound);

                Lines.Clear();
                byte[] bookdata = doc.GetStreamData("Workbook");
                if (bookdata == null)
                    throw new InvalidOperationException(Constants.Messages.Error_ExcelFileNoWorkbook);

                Workbook workbook = WorkbookDecoder.Decode(new MemoryStream(bookdata));
                if (workbook.Worksheets.Count == 0)
                    throw new InvalidOperationException(Constants.Messages.Error_ExcelFileNoWorksheet);

                Worksheet sheet = workbook.Worksheets[0];
                m_WorksheetName = sheet.Name;
                for (int rowIndex = sheet.Cells.FirstRowIndex; rowIndex <= sheet.Cells.LastRowIndex; rowIndex++)
                {
                    SourceLine line = new SourceLine();
                    Row row = sheet.Cells.GetRow(rowIndex);
                    bool bBlank = true;
                    for (int colIndex = row.FirstColIndex; colIndex <= row.LastColIndex; colIndex++)
                    {
                        Cell cell = row.GetCell(colIndex);
                        line.Columns.Add(cell.StringValue);
                        if (cell.StringValue != null && cell.StringValue.Length > 0)
                            bBlank = false;
                    }
                    if (!bBlank)
                        Lines.Add(line);
                }

                doc.Close();
                return true;
            }
            catch
            {
                Lines.Clear();
                throw;
            }
            finally
            {
                if (this.FileParsed != null)
                    this.FileParsed();
            }
        }
        /// <summary>
        /// write a line to the report
        /// </summary>
        /// <param name="actLine">information about the action</param>
        /// <param name="result">result of the action</param>
        public void WriteLine(ActionLine actLine, ActionResult result)
        {
            SourceLine line = new SourceLine();
            for (int i = 0; i < Indent + 1; i++)
                line.Columns.Add(string.Empty);

            line.Columns.Add(actLine.ActionName);
            if (actLine.WindowName != null || actLine.ControlName != null)
            {
                line.Columns.Add(actLine.WindowName != null ? actLine.WindowName : string.Empty);
                line.Columns.Add(actLine.ControlName != null ? actLine.ControlName : string.Empty);
            }
            foreach (string key in actLine.Arguments.Keys)
                line.Columns.Add(key + Constants.PropertyDelimeter + actLine.Arguments[key]);
            line.Columns.Add(result != ActionResult.NORET ? result.ToString() : string.Empty);

            if (result == ActionResult.PASSED || result == ActionResult.FAILED)
            {
                TotalCheck++;
                if (result == ActionResult.PASSED)
                    TotalPassed++;
            }
            else if (result == ActionResult.WARNING)
                TotalWarning++;

            Lines.Add(line);
        }
        /// <summary>
        /// write an error to the report
        /// </summary>
        /// <param name="actLine">the error action line</param>
        /// <param name="why">the reason</param>
        public void WriteError(ActionLine actLine, string why)
        {
            SourceLine line = new SourceLine();
            for (int i = 0; i < Indent + 1; i++)
                line.Columns.Add(string.Empty);

            line.Columns.Add(actLine.ActionName);
            if (actLine.WindowName != null || actLine.ControlName != null)
            {
                line.Columns.Add(actLine.WindowName != null ? actLine.WindowName : string.Empty);
                line.Columns.Add(actLine.ControlName != null ? actLine.ControlName : string.Empty);
            }
            foreach (string key in actLine.Arguments.Keys)
                line.Columns.Add(key + Constants.PropertyDelimeter + actLine.Arguments[key]);
            line.Columns.Add(Constants.ReportText.ErrorLinePrefix + why);

            Lines.Add(line);
        }
        /// <summary>
        /// end current 'script' section
        /// </summary>
        /// <param name="scriptName">name of the script</param>
        public void EndScript(string scriptName)
        {
            SourceLine line = new SourceLine();
            for (int i = 0; i < Indent; i++)
                line.Columns.Add(string.Empty);

            line.Columns.Add(Constants.ReportText.EndScript);
            line.Columns.Add(scriptName);

            Lines.Add(line);

            Indent--;
        }
        /// <summary>
        /// close current report and save to file
        /// </summary>
        public bool EndReport()
        {
            SourceLine line = new SourceLine();
            line.Columns.Add(Constants.ReportText.EndReport);
            line.Columns.Add(Name);

            Lines.Add(line);

            line = new SourceLine();
            line.Columns.Add(Constants.ReportText.SummaryReport);
            line.Columns.Add(Constants.ReportText.TotalCheck + TotalCheck.ToString());
            line.Columns.Add(Constants.ReportText.TotalPassed + TotalPassed.ToString());
            line.Columns.Add(Constants.ReportText.TotalWarning + TotalWarning.ToString());
            Lines.Insert(1, line);

            try
            {
                Parser.Save(Name);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// create new report
        /// </summary>
        /// <param name="name">name of the report</param>
        /// <param name="datasetName">name of the dataset</param>
        public void BeginReport(string name, string datasetName)
        {
            Name = name;
            Parser.Create(Constants.ReportText.ReportNamePrefix + DateTime.Now.ToString(Constants.ReportText.ReportDateFormat));

            SourceLine line = new SourceLine();
            line.Columns.Add(Constants.ReportText.BeginReport);
            line.Columns.Add(name);

            Lines.Add(line);

            if (datasetName != null)
            {
                line = new SourceLine();
                line.Columns.Add(Constants.ReportText.BeginDataSet);
                line.Columns.Add(datasetName);
                Lines.Add(line);
            }
        }