// 
// Starter sample for fallback fonts
//
// Required data: suitable fonts
//

using System;
using System.Text;
using PDFlib_dotnet;

struct testcase {
    public string usecase;
    public string fontname;
    public string fallbackoptions;
    public string text;
    // Constructor
    public testcase(string usecase, string fontname, string fallbackoptions, string text)
    {
        this.usecase = usecase;
        this.fontname = fontname;
        this.fallbackoptions = fallbackoptions;
        this.text = text;
    }
};

class starter_fallback {
  static int Main(string[] args) {

        /* This is where the data files are. Adjust as necessary. */
        string searchpath = "../../../data";
        string outfile = "starter_fallback.pdf";

        StringBuilder optlist = new StringBuilder();;
        PDFlib p = null;
        int row, col, table, test;
        double llx= 30, lly=50, urx=800, ury=570;
        string result;

        string[] header = {
            "Use case",
            "Option list for the 'fallbackfonts' option",
            "Base font",
            "With fallback font"
        };
        int MAXCOL = header.Length;

        testcase[] testcases = {
          new testcase("Add enlarged pictogram",
          "NotoSerif-Regular",
          // U+261E = WHITE RIGHT POINTING INDEX
          "{fontname=ZapfDingbats forcechars=U+261E " +
          "fontsize=150% textrise=-15%}",
          "hand symbol: &#x261E;"),
          new testcase("Add enlarged symbol glyph",
          "NotoSerif-Regular",
          "{fontname=Symbol forcechars=U+2663 fontsize=125%}",
           "club symbol: &#x2663;"),
          // Hebrew characters missing in the font will be pulled from Hebrew
          new testcase( "Add Hebrew characters to Latin font", 
            "NotoSerif-Regular", 
            "{fontname=NotoSerifHebrew-Regular}",
            "Hebrew: &#x05D0;"),
    };
    int n_testcases = testcases.Length;

    try {
        /* create a new PDFlib object */
        p = new PDFlib();

        
        /* This means that formatting and other errors will raise an
         * exception. This simplifies our sample code, but is not
         * recommended for production code.
         */

        p.set_option("errorpolicy=exception");

        // Set the search path for fonts and PDF files 
        p.set_option("SearchPath={{" + searchpath + "}} glyphcheck=replace charref=true");


        /* Set an output path according to the name of the topic */
        if (p.begin_document(outfile, "") == -1) {
            Console.WriteLine("Error: {0}\n", p.get_errmsg());
            return(2);
        }

        p.set_info("Creator", "PDFlib starter sample");
        p.set_info("Title", "starter_fallback");

        /* Start Page */
        p.begin_page_ext(0, 0, "width=a4.height height=a4.width");

        table = -1;

        /* Table header */
        for (row=1, col=1; col <= MAXCOL; col++)
        {
            optlist.Length = 0;
            optlist.Append("fittextline={fontname=NotoSerif-Regular " +
                "fontsize=10} margin=4");
            table = p.add_table_cell(table, col, row, header[col-1],
                    optlist.ToString());
        }

        /* Create fallback samples, one use case per row */
        for (row=2, test=0; test < n_testcases; row++, test++)
        {
            col=1;

            /* Column 1: description of the use case */
            optlist.Length = 0;
            optlist.Append("fittextline={fontname=NotoSerif-Regular " +
                    "fontsize=10} margin=4");
            table = p.add_table_cell(table, col++, row,
                testcases[test].usecase, optlist.ToString());

            /* Column 2: reproduce option list literally */
            optlist.Length = 0;
            optlist.Append("fittextline={fontname=NotoSerif-Regular " +
                    "fontsize=10} margin=4");
            table = p.add_table_cell(table, col++, row,
                testcases[test].fallbackoptions, optlist.ToString());

            /* Column 3: text with base font */
            optlist.Length = 0;
            optlist.Append("fittextline={fontname=");
            optlist.AppendFormat("{0}", testcases[test].fontname);
            optlist.Append("");
            optlist.Append(" fontsize=10 replacementchar=? } margin=4");
            table = p.add_table_cell(table, col++, row,
                        testcases[test].text, optlist.ToString());

            /* Column 4: text with base font and fallback fonts */
            optlist.Length = 0;
            optlist.Append("fittextline={fontname=");
            optlist.AppendFormat("{0}", testcases[test].fontname);
            optlist.Append("");
            optlist.Append(" fontsize=10 fallbackfonts={");
            optlist.AppendFormat("{0}", testcases[test].fallbackoptions);
            optlist.Append("}} margin=4");
            table = p.add_table_cell(table, col++, row,
               testcases[test].text, optlist.ToString());
        }

        /* Place the table */
        optlist.Length = 0;
        optlist.Append("header=1 fill={{area=rowodd " +
            "fillcolor={gray 0.9}}} stroke={{line=other}} ");
        result = p.fit_table(table, llx, lly, urx, ury, optlist.ToString());

        if (result == "_error")
        {
            Console.WriteLine("Couldn't place table: {0}\n",p.get_errmsg());
            return(2);
        }

        p.end_page_ext("");
        p.end_document("");
    }

    catch (PDFlibException e)
    {
        // caught exception thrown by PDFlib
        Console.WriteLine("PDFlib exception occurred:");
        Console.WriteLine("[{0}] {1}: {2}\n", e.get_errnum(),
                e.get_apiname(), e.get_errmsg());
    } finally {
        if (p != null) {
            p.Dispose();
        }
    }
    return(0);
  }
}
