using Microsoft.AspNetCore.Html; using Microsoft.Office.Interop.Word; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows; namespace JRCookbookBusiness { public class Cookbook { public Guid? cookbookID = null; public String author = String.Empty; public String copyright = String.Empty; public String name = String.Empty; public String comments = String.Empty; public List cookbookChapters = new List(); public List recipeHighlights = new List(); private int mNumberRecipiesRendered = 0; private int mTotalNumberRecipiesToRender = 0; public event EventHandler LongRunningStatusUpdatedEvent; public Cookbook() { } public Cookbook(Guid cookbookID) { PopulateByID(cookbookID); } public void Save() { if (this.cookbookID == null) { this.cookbookID = clsDatabaseLayer.GetDatabaseLayer().GetNewIDCookbook(); clsDatabaseLayer.GetDatabaseLayer().InsertCookbook(this); } else { clsDatabaseLayer.GetDatabaseLayer().UpdateCookbook(this); } } public void Delete() { foreach(var cookbookChapter in cookbookChapters) { cookbookChapter.Delete(); } foreach (var recipe in recipeHighlights) { recipe.Delete(); } clsDatabaseLayer.GetDatabaseLayer().DeleteCookbookByID(cookbookID.Value); } public static Cookbook GetCookbookByID(Guid cookbookID) { return new Cookbook(cookbookID); } public static Cookbook GetCookbookByDataRow(DataRow row) { var newCookbook = new Cookbook(); newCookbook.PopulateFromDataRow(row); return newCookbook; } public static List GetAllCookbooks() { DataSet recordSet; var returnValue = new List(); recordSet = clsDatabaseLayer.GetDatabaseLayer().GetAllCookbooks(); if (recordSet.Tables[0].Rows.Count > 0) { foreach (DataRow ldbrwRow in recordSet.Tables[0].Rows) { var newCookbook = new Cookbook(); newCookbook.PopulateFromDataRow(ldbrwRow); returnValue.Add(newCookbook); } } return returnValue; } private void PopulateByID(Guid cookbookID) { DataSet recordSet; recordSet = clsDatabaseLayer.GetDatabaseLayer().GetCookbookByID(cookbookID); if (recordSet.Tables[0].Rows.Count > 0) { DataRow ldbrwRow; ldbrwRow = recordSet.Tables[0].Rows[0]; PopulateFromDataRow(ldbrwRow); } } private void PopulateFromDataRow(DataRow dataRow) { InitializeAllFields(); if (dataRow.IsNull("cookbookID")) cookbookID = null; else cookbookID = (Guid)dataRow["cookbookID"]; if (dataRow.IsNull("author")) author = String.Empty; else author = (String)dataRow["author"]; if (dataRow.IsNull("copyright")) copyright = String.Empty; else copyright = (String)dataRow["copyright"]; if (dataRow.IsNull("name")) name = String.Empty; else name = (String)dataRow["name"]; if (dataRow.IsNull("comments")) comments = String.Empty; else comments = (String)dataRow["comments"]; LoadChapters(); LoadRecipeHighlights(); } private void InitializeAllFields() { cookbookID = null; author = String.Empty; copyright = String.Empty; name = String.Empty; comments = String.Empty; cookbookChapters = new List(); recipeHighlights = new List(); } private void LoadChapters() { //Populate child objects DataSet recordSet; recordSet = clsDatabaseLayer.GetDatabaseLayer().GetCookbookChaptersByParentChapter(this.cookbookID.Value, null); foreach (DataRow childDataRow in recordSet.Tables[0].Rows) { var newChapter = CookbookChapter.GetCookbookChapterByDataRow(childDataRow); cookbookChapters.Add(newChapter); } } private void LoadRecipeHighlights() { //Populate child objects DataSet recordSet; recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeHighlightsByParentChapter(this.cookbookID.Value, null); foreach (DataRow childDataRow in recordSet.Tables[0].Rows) { var newRecipeHighlights = RecipeHighlights.GetRecipeHighlightsByDataRow(childDataRow); recipeHighlights.Add(newRecipeHighlights); } } public void GenerateWebPages(String folderToSaveTo) { var recipePageDictionary = new Dictionary(); var pagesAlreadyAdded = new SortedSet(); var recipesAlpha = new SortedList(); //var strCookbookPage = SharedRoutines.RemoveSpecialCharactersFromFileName(this.name); var strCookbookPage = SharedRoutines.RemoveSpecialCharactersFromFileName("index"); var strCookbookPageWithExtension = strCookbookPage + ".htm"; while (pagesAlreadyAdded.Contains(strCookbookPageWithExtension.ToUpper())) { strCookbookPage += "1"; strCookbookPageWithExtension = strCookbookPage + ".htm"; } pagesAlreadyAdded.Add(strCookbookPageWithExtension.ToUpper()); var builderCookbookIndex = new HtmlContentBuilder(); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendFormat("{0}" + Constants.CRLF, this.name); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendHtml(HTMLAddCookbookName()); List trackbackList = new List(); Trackback thisTrackback = new Trackback(); thisTrackback.TrackbackURL = strCookbookPageWithExtension; thisTrackback.TrackbackText = this.name; trackbackList.Add(thisTrackback); foreach (var cookbookChapter in cookbookChapters) { cookbookChapter.RecipeRenderedEvent += HandleRecipeRendered; var chapterURLAdded = cookbookChapter.GenerateWebPagesToFolder(folderToSaveTo, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, trackbackList); builderCookbookIndex.AppendHtml(HTMLAddSubChapterToIndex(cookbookChapter, chapterURLAdded)); cookbookChapter.RecipeRenderedEvent -= HandleRecipeRendered; } foreach (var recipeHighlight in recipeHighlights) { var recipe = Recipe.GetRecipeByID(recipeHighlight.recipeID.Value); recipe.RecipeRenderedEvent += HandleRecipeRendered; recipe.GenerateWebPageToFolder(folderToSaveTo, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, trackbackList); builderCookbookIndex.AppendHtml(HTMLAddRecipeToIndex(recipe, recipePageDictionary)); recipe.RecipeRenderedEvent -= HandleRecipeRendered; } var allRecipesURLAdded = GenerateCookbookAllRecipesWebPageIndex(folderToSaveTo, strCookbookPage, recipePageDictionary, recipesAlpha, pagesAlreadyAdded); builderCookbookIndex.AppendHtml(HTMLAddAllRecipesItemToIndex(allRecipesURLAdded)); var strIndexPath = folderToSaveTo; if (strIndexPath.EndsWith("\\") == false) { strIndexPath += "\\"; } builderCookbookIndex.AppendHtmlLine("
"); builderCookbookIndex.AppendHtmlLine(""); builderCookbookIndex.AppendHtmlLine(""); strIndexPath += strCookbookPageWithExtension; using (var writer = new System.IO.StreamWriter(strIndexPath, false)) { builderCookbookIndex.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); } } private String HTMLAddSubChapterToIndex(CookbookChapter chapter, String chapterURL) { var builder = new HtmlContentBuilder(); builder.AppendHtmlLine(" "); builder.AppendHtmlLine(" "); builder.AppendHtml("

"); builder.AppendFormat("", chapterURL); builder.AppendFormat("{0}", chapter.name); builder.AppendHtmlLine(""); builder.AppendHtmlLine("

"); builder.AppendHtmlLine(" "); builder.AppendHtmlLine(" "); using (var writer = new System.IO.StringWriter()) { builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); return writer.ToString(); } } private String GenerateCookbookAllRecipesWebPageIndex(String folderToSaveTo, String cookbookPageName, Dictionary recipePageDictionary, SortedList recipesAlpha, SortedSet pagesAlreadyAdded) { var builderAllRecipeIndex = new HtmlContentBuilder(); var builderChapterIndex = new HtmlContentBuilder(); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendFormat("{0}" + Constants.CRLF, this.name); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendHtml(HTMLAddCookbookName()); foreach (var recipe in recipesAlpha.Values) { builderAllRecipeIndex.AppendHtml(HTMLAddRecipeToIndex(recipe, recipePageDictionary)); } builderAllRecipeIndex.AppendHtmlLine("
"); builderAllRecipeIndex.AppendHtmlLine(""); builderAllRecipeIndex.AppendHtmlLine(""); var strIndexPath = folderToSaveTo; if (strIndexPath.EndsWith("\\") == false) { strIndexPath += "\\"; } var strPageName = cookbookPageName + "-allrecipes"; var strPageNameWithExtension = strPageName + ".htm"; while (pagesAlreadyAdded.Contains(strPageNameWithExtension.ToUpper())) { strPageName += "1"; strPageNameWithExtension = strPageName + ".htm"; } pagesAlreadyAdded.Add(strPageNameWithExtension.ToUpper()); strIndexPath += strPageNameWithExtension; using (var writer = new System.IO.StreamWriter(strIndexPath, false)) { builderAllRecipeIndex.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); } return strPageNameWithExtension; } private String HTMLAddCookbookName() { var builder = new HtmlContentBuilder(); builder.AppendHtmlLine(" "); builder.AppendHtmlLine(" "); builder.AppendHtml("

"); builder.AppendFormat("{0}", this.name); builder.AppendHtmlLine("

"); builder.AppendHtmlLine(" "); builder.AppendHtmlLine(" "); using (var writer = new System.IO.StringWriter()) { builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); return writer.ToString(); } } private String HTMLAddRecipeToIndex(Recipe recipe, Dictionary recipePageDictionary) { var recipePageURL = recipePageDictionary.GetValueOrDefault(recipe.recipeID.Value, String.Empty); var builder = new HtmlContentBuilder(); builder.AppendHtmlLine(" "); builder.AppendHtmlLine(" "); builder.AppendHtml("

"); builder.AppendFormat("", recipePageURL); builder.AppendFormat("{0}", recipe.recipename); builder.AppendHtmlLine(""); builder.AppendHtmlLine("

"); builder.AppendHtmlLine(" "); builder.AppendHtmlLine(" "); using (var writer = new System.IO.StringWriter()) { builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); return writer.ToString(); } } private String HTMLAddAllRecipesItemToIndex(String allRecipesURL) { var builder = new HtmlContentBuilder(); builder.AppendHtmlLine(" "); builder.AppendHtmlLine(" "); builder.AppendHtml("

"); builder.AppendFormat("", allRecipesURL); builder.AppendFormat("{0}", "All Recipes"); builder.AppendHtmlLine(""); builder.AppendHtmlLine("

"); builder.AppendHtmlLine(" "); builder.AppendHtmlLine(" "); using (var writer = new System.IO.StringWriter()) { builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); return writer.ToString(); } } public void GenerateWordDoc(String fileToSaveTo) { try { var recipePageDictionary = new Dictionary(); var pagesAlreadyAdded = new SortedSet(); var recipesAlpha = new SortedList(); mTotalNumberRecipiesToRender = this.GetTotalRecipeCount(); mNumberRecipiesRendered = 0; clsWord.ResetWord(); clsWord.WordApplication.Documents.Add(); clsWord.WordApplication.ActiveDocument.PageSetup.LeftMargin = clsWord.WordApplication.InchesToPoints(0.5F); clsWord.WordApplication.ActiveDocument.PageSetup.RightMargin = clsWord.WordApplication.InchesToPoints(0.5F); clsWord.WordApplication.ActiveDocument.PageSetup.TopMargin = clsWord.WordApplication.InchesToPoints(0.5F); clsWord.WordApplication.ActiveDocument.PageSetup.BottomMargin = clsWord.WordApplication.InchesToPoints(0.5F); clsWord.WordApplication.Selection.ParagraphFormat.SpaceBefore = 0; clsWord.WordApplication.Selection.ParagraphFormat.SpaceAfter = 0; clsWord.WordApplication.Selection.ParagraphFormat.SpaceAfterAuto = 0; clsWord.WordApplication.Selection.ParagraphFormat.LineUnitBefore = 0; clsWord.WordApplication.Selection.ParagraphFormat.LineUnitAfter = 0; //clsWord.WordApplication.ActiveDocument.Styles["Heading 1"].Font.Size = clsWord.WORD_CHAPTER_NAME_FONT_SIZE; //clsWord.WordApplication.ActiveDocument.Styles["Heading 2"].Font.Size = clsWord.WORD_RECIPE_NAME_FONT_SIZE; var baseFontName = clsWord.WordApplication.Selection.Font.Name; var heading1Style = clsWord.WordApplication.ActiveDocument.Styles["Heading 1"]; heading1Style.Font.Name = baseFontName; heading1Style.Font.Size = clsWord.WORD_CHAPTER_NAME_FONT_SIZE; heading1Style.Font.Bold = 1; heading1Style.Font.Italic = 0; heading1Style.Font.Underline = WdUnderline.wdUnderlineNone; heading1Style.AutomaticallyUpdate = true; heading1Style.set_BaseStyle("Normal"); heading1Style.set_NextParagraphStyle("Normal"); var heading2Style = clsWord.WordApplication.ActiveDocument.Styles["Heading 2"]; heading2Style.Font.Name = baseFontName; heading2Style.Font.Size = clsWord.WORD_RECIPE_NAME_FONT_SIZE; heading2Style.Font.Bold = 1; heading2Style.Font.Italic = 0; heading2Style.Font.Underline = WdUnderline.wdUnderlineNone; heading2Style.AutomaticallyUpdate = true; heading2Style.set_BaseStyle("Normal"); heading2Style.set_NextParagraphStyle("Normal"); var toc1Style = clsWord.WordApplication.ActiveDocument.Styles["TOC 1"]; toc1Style.AutomaticallyUpdate = true; toc1Style.set_BaseStyle("Normal"); toc1Style.set_NextParagraphStyle("Normal"); toc1Style.Font.Name = baseFontName; toc1Style.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; toc1Style.ParagraphFormat.SpaceBefore = 0F; toc1Style.ParagraphFormat.SpaceBeforeAuto = 0; toc1Style.ParagraphFormat.SpaceAfter = 0F; toc1Style.ParagraphFormat.SpaceAfterAuto = 0; toc1Style.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle; var toc2Style = clsWord.WordApplication.ActiveDocument.Styles["TOC 2"]; toc2Style.AutomaticallyUpdate = true; toc2Style.set_BaseStyle("Normal"); toc2Style.set_NextParagraphStyle("Normal"); toc2Style.Font.Name = baseFontName; toc2Style.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; toc2Style.ParagraphFormat.SpaceBefore = 0F; toc2Style.ParagraphFormat.SpaceBeforeAuto = 0; toc2Style.ParagraphFormat.SpaceAfter = 0F; toc2Style.ParagraphFormat.SpaceAfterAuto = 0; toc2Style.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle; clsWord.WordApplication.Selection.Font.Size = clsWord.WORD_RECIPE_SECTION_HEADING_FONT_SIZE; clsWord.WordApplication.Selection.Font.Bold = 1; clsWord.WordApplication.Selection.TypeText(this.name); clsWord.WordApplication.Selection.TypeParagraph(); clsWord.WordApplication.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; clsWord.WordApplication.Selection.Font.Bold = 0; clsWord.WordApplication.Selection.InsertNewPage(); clsWord.WordApplication.Selection.Bookmarks.Add("TableOfContents"); bool isFirstPageOfContent = true; foreach (var cookbookChapter in cookbookChapters) { cookbookChapter.RecipeRenderedEvent += HandleRecipeRendered; cookbookChapter.AddToWordDoc(clsWord.WordApplication, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, ref isFirstPageOfContent); cookbookChapter.RecipeRenderedEvent += HandleRecipeRendered; } if (recipeHighlights.Count > 0) { clsWord.WordApplication.Selection.InsertBreak(WdBreakType.wdSectionBreakNextPage); clsWord.Insert_HeaderText(String.Empty); clsWord.Insert_PageNumberFooter(ref isFirstPageOfContent); } foreach (var recipeHighlight in recipeHighlights) { var recipe = Recipe.GetRecipeByID(recipeHighlight.recipeID.Value); recipe.RecipeRenderedEvent += HandleRecipeRendered; recipe.AddToWordDoc(clsWord.WordApplication, recipePageDictionary, recipesAlpha, pagesAlreadyAdded); recipe.RecipeRenderedEvent -= HandleRecipeRendered; } clsWord.WordApplication.Selection.InsertBreak(WdBreakType.wdSectionBreakNextPage); clsWord.Insert_HeaderText(String.Empty); clsWord.Insert_PageNumberFooter(ref isFirstPageOfContent); clsWord.WordApplication.ActiveDocument.Indexes.Add(clsWord.WordApplication.Selection.Range, Microsoft.Office.Interop.Word.WdHeadingSeparator.wdHeadingSeparatorNone, 1, NumberOfColumns: 2, IndexLanguage: Microsoft.Office.Interop.Word.WdLanguageID.wdEnglishUS); clsWord.WordApplication.ActiveDocument.Indexes[1].TabLeader = Microsoft.Office.Interop.Word.WdTabLeader.wdTabLeaderDots; if (clsWord.WordApplication.ActiveDocument.Bookmarks.Exists("TableOfContents")) { clsWord.WordApplication.Selection.GoTo(Microsoft.Office.Interop.Word.WdGoToItem.wdGoToBookmark, Name: "TableOfContents"); clsWord.WordApplication.ActiveDocument.TablesOfContents.Add(clsWord.WordApplication.Selection.Range, RightAlignPageNumbers: true, IncludePageNumbers: true); clsWord.WordApplication.ActiveDocument.TablesOfContents[1].Update(); } clsWord.WordApplication.ActiveDocument.SaveAs2(fileToSaveTo); clsWord.WordApplication.ActiveDocument.Close(); } catch(Exception ex) { MessageBox.Show("Error creating document " + ex.ToString()); } finally { clsWord.ShutDownWord(); } } private void HandleRecipeRendered(object sender, System.EventArgs e) { mNumberRecipiesRendered += 1; if (LongRunningStatusUpdatedEvent != null) { LongRunningStatusUpdatedEvent.Invoke(this, new LongRunningStatusUpdatedEventArgs("Rendered " + mNumberRecipiesRendered.ToString() + " of " + mTotalNumberRecipiesToRender.ToString(), mNumberRecipiesRendered, mTotalNumberRecipiesToRender)); } } public int GetTotalRecipeCount() { int returnValue = 0; foreach (var cookbookChapter in cookbookChapters) { returnValue += cookbookChapter.GetTotalRecipeCount(); } returnValue += recipeHighlights.Count; return returnValue; } } }