SimpleTable.cs
//
// This code is part of GrapeCity Documents for Word samples.
// Copyright (c) GrapeCity, Inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using GrapeCity.Documents.Word;

namespace GcWordWeb.Samples
{
    // This sample creates a simple table,
    // and demonstrates the following table related tasks:
    // - Applying table styles (borders and padding);
    // - Adding rows and cells;
    // - Removing rows;
    // - Fetching text from a specific cell;
    // - Applying character style to a specific cell.
    public class SimpleTable
    {
        public GcWordDocument CreateDocx()
        {
            GcWordDocument doc = new GcWordDocument();

            // Random-ish table dimensions:
            var rand = new Random((int)DateTime.Now.Ticks);
            var rows = rand.Next(15, 100);
            var cols = rand.Next(4, 6);
            var getrow = rand.Next(0, 10);
            var getcol = rand.Next(0, 4);
            var badrow = 12; // index 12 === number 13 :)

            var section = doc.Body.Sections.First;
            var header = section.GetRange().Paragraphs.Add(
                $"A {cols} columns by {rows} rows table (note that the there's no 'row {badrow + 1}'):");

            // Add an empty table:
            var t = section.GetRange().Tables.Add(0, 0);

            // Add some rows and cells to it:
            var cells = new List<string>(cols);
            for (int col = 0; col < cols; ++col)
                cells.Add(string.Empty);
            for (int row = 0; row < rows; ++row)
            {
                for (int col = 0; col < cols; ++col)
                    cells[col] = $"Row {row + 1}, col {col + 1}";
                t.Rows.Add(cells.ToArray());
            }
            // Remove a row:
            t.Rows[badrow].Delete();

            // Create a new table style:
            var ts1 = doc.Styles.Add("Table Style 1", StyleType.Table);
            // Assign the style to the table:
            t.Style = ts1;

            // We can enumerate all table borders, including inside borders:
            foreach (var border in ts1.Table.Borders)
            {
                border.LineStyle = LineStyle.Triple;
                border.LineWidth = 0.5f;
                border.Color.RGB = Color.Purple;
            }
            // Overwrite inside border's line styles:
            ts1.Table.Borders.InsideHorizontal.LineStyle =
                ts1.Table.Borders.InsideVertical.LineStyle =
                LineStyle.Double;
            // Add some cell padding:
            ts1.Table.Padding.All = 2;

            // Finally, fetch the text from a certain cell and insert it before the table:

            // Fetching the text from a cell: because we know exactly the structure of our table,
            // we can do this without any checks:
            // - get the cell at index 'getcol' in row 'getrow',
            // - first child fetches the paragraph,
            // - next child fetches the run,
            // - finally, next child fetches the actual text element:
            var text = t.Rows[getrow].Cells[getcol].Children.First().Children.First().Children.First() as Text;
            // Get the parent run:
            var run = text.ParentContent as Run;
            // Mark the found cell with bold/italic font:
            var rs1 = doc.Styles.Add("cell hi-light", StyleType.Character);
            rs1.Font.Bold = true;
            rs1.Font.Italic = true;
            run.Style = rs1;
            // Add the fetched text from cell (2,0) before the document's opening paragraph, 
            // using the same character style:
            var pp = header.GetRange().Paragraphs.Insert(
                $"Text from cell at row {getrow + 1}, col {getcol + 1} (drawn with bold/italic font): \"", InsertLocation.Before);
            var r = pp.GetRange().Runs.Add(text.Value);
            r.Style = rs1;
            pp.GetRange().Runs.Add("\".");

            // Done:
            return doc;
        }
    }
}