RdFieldOpts.cs
//
// This code is part of Document Solutions for Word demos.
// Copyright (c) MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using GrapeCity.Documents.Word;
using GrapeCity.Documents.Word.Fields;

namespace DsWordWeb.Demos
{
    // This sample shows how to add an RD field to a Word document,
    // and specify its options.
    public class RdFieldOpts
    {
        public GcWordDocument CreateDocx()
        {
            // Create a few sub-documents to be referenced in the main document:
            const int SubDocCount = 3;
            var tFnames = new List<string>();
            for (int i = 1; i <= SubDocCount; i++)
            {
                var subDoc = new GcWordDocument();

                // Set the starting page number for each sub-document:
                subDoc.Body.Sections.First.PageSetup.PageNumbering.StartingNumber = i + 1;

                // Add a heading to be referenced in the main document's TOC:
                subDoc.Body.AddParagraph($"Heading from sub-document {i}.", subDoc.Styles[BuiltInStyleId.Heading1]);

                // Add a table of authorities entry to be referenced in the main document:
                var ta = new TaFieldOptions(subDoc);
                ta.Category = 1;
                ta.LongCitation.Text = $"Table of authorities entry from sub-document {i}.";
                var p = subDoc.Body.AddParagraph();
                p.AddComplexField(ta);
                p.AddRun($"Table of authorities entry from sub-document {i}.");

                // Add an index entry to be referenced in the main document:
                var xe = new XeFieldOptions(subDoc);
                xe.Entry.Content.Text = $"Index entry from sub-document {i}";
                p = subDoc.Body.AddParagraph();
                p.AddComplexField(xe);
                p.AddRun($"Index entry from sub-document {i}.");

                tFnames.Add(Path.GetTempFileName());
                subDoc.Save(tFnames.Last());
            }

            // Create the main document to store TOC, TOA an index information from sub documents:
            var doc = new GcWordDocument();

            // Create the TOC field:
            var toc = new TocFieldOptions(doc);
            var h = doc.Body.AddParagraph("Table of Contents", doc.Styles[BuiltInStyleId.Title]);
            h.AddComplexField(toc);

            // Create the TOA field:
            var toa = new ToaFieldOptions(doc);
            h = doc.Body.AddParagraph("Table of Authorities", doc.Styles[BuiltInStyleId.Title]);
            h.AddComplexField(toa);

            // Create the INDEX field:
            var index = new IndexFieldOptions(doc);
            index.PageNumbers.Separator = "\t";
            h = doc.Body.AddParagraph("Index", doc.Styles[BuiltInStyleId.Title]);
            h.AddComplexField(index);

            // Add RD fields to the main document referencing the sub-documents:
            for (int i = 1; i <= SubDocCount; i++)
            {
                var rd = new RdFieldOptions(doc)
                {
                    FilePath = ToUri(tFnames[i - 1]).ToString(),
                    Relative = false
                };
                h = doc.Body.AddParagraph();
                h.AddComplexField(rd);
            }

            // Update all fields in the main document that collects TOC, TOA and index entries from sub documents,
            // using a specific culture:
            doc.UpdateFields(new GrapeCity.Documents.Word.Layout.WordLayoutSettings() { FontCollection = Util.FontCollection, Culture = CultureInfo.GetCultureInfo("en-US") });

            // As this is a demo, clean up temporary sub-document files:
            tFnames.ForEach(f => File.Delete(f));
            return doc;
        }

        static Uri ToUri(string pathOrUrl)
        {
            // If it's already an absolute URI (http, https, ftp, file, etc.):
            if (Uri.TryCreate(pathOrUrl, UriKind.Absolute, out var existing))
            {
                return existing;
            }
            // Otherwise treat it as a file path:
            return new Uri(Path.GetFullPath(pathOrUrl));
        }
    }
}