# Ruby on Rails examples for PDFlib
# vim: sw=2

class PdflibController < ApplicationController
  def hello
    send_data hello_pdf, :filename => "hello.pdf", :type => "application/pdf",
	:disposition => "inline"
  end
  def image
    send_data image_pdf, :filename => "image.pdf", :type => "application/pdf",
	:disposition => "inline"
  end
  def pdfclock
    send_data pdfclock_pdf, :filename => "pdfclock.pdf",
	:type => "application/pdf", :disposition => "inline"
  end
  def chartab
    send_data chartab_pdf, :filename => "chartab.pdf",
	:type => "application/pdf", :disposition => "inline"
  end
  def invoice
    send_data invoice_pdf, :filename => "invoice.pdf",
	:type => "application/pdf", :disposition => "inline"
  end
  def quickreference
    send_data quickreference_pdf, :filename => "quickreference.pdf",
	:type => "application/pdf", :disposition => "inline"
  end
  def businesscard
    send_data businesscard_pdf, :filename => "businesscard.pdf",
	:type => "application/pdf", :disposition => "inline"
  end
end

require 'PDFlib'

private

  # PDFlib hello example
  def hello_pdf

    p = PDFlib.new

    if (p.begin_document("", "") == -1)
      raise "Error: " + p.get_errmsg
    end

    p.set_info("Creator", "hello.rb")
    p.set_info("Author", "Thomas Merz")
    p.set_info("Title", "Hello world (Ruby)!")

    p.begin_page_ext(595, 842, "")

    font = p.load_font("Helvetica-Bold", "winansi", "")

    p.setfont(font, 24)

    p.set_text_pos(50, 700)
    p.show("Hello world!")
    p.continue_text("(says Ruby)")
    p.end_page_ext("")

    p.end_document("")

    p.get_buffer()
  end


  def image_pdf
    imagefile = "nesrin.jpg"
    # This is where font/image/PDF input files live. Adjust as necessary.
    searchpath = "../../data"

    p = PDFlib.new

    if (p.begin_document("", "") == -1)
      raise "Error: " + p.get_errmsg()
    end

    p.set_parameter("SearchPath", searchpath)

    p.set_info("Creator", "image.rb")
    p.set_info("Author", "Thomas Merz")
    p.set_info("Title", "image sample (Ruby)")

    image = p.load_image("auto", imagefile, "")

    if (image == -1)
      raise "Error: " + p.get_errmsg()
    end

    # dummy page size, will be adjusted by PDF_fit_image()
    p.begin_page_ext(10, 10, "")
    p.fit_image(image, 0.0, 0.0, "adjustpage")
    p.close_image(image)
    p.end_page_ext("")

    p.end_document("")

    p.get_buffer()
  end



  def pdfclock_pdf
    radius = 200.0
    margin = 20.0
    time = Time.now	# TODO: use the correct (local) time

    p = PDFlib.new

    if (p.begin_document("", "") == -1)
      raise "Error: " + p.get_errmsg
    end

    p.set_info("Creator", "pdfclock.rb")
    p.set_info("Author", "Thomas Merz")
    p.set_info("Title", "PDF clock (Ruby)")

    p.begin_page_ext( (2 * (radius + margin)), (2 * (radius + margin)), "")

    p.translate(radius + margin, radius + margin)
    p.setcolor("fillstroke", "rgb", 0.0, 0.0, 1.0, 0.0)
    p.save

    # minute strokes 
    p.setlinewidth(2.0)
    0.step(360, 6) do |alpha|
      p.rotate(6.0)
      p.moveto(radius, 0.0)
      p.lineto(radius-margin/3, 0.0)
      p.stroke
    end

    p.restore
    p.save

    # 5 minute strokes
    p.setlinewidth(3.0)
    0.step(360, 30) do |alpha|
      p.rotate(30.0)
      p.moveto(radius, 0.0)
      p.lineto(radius-margin, 0.0)
      p.stroke
    end

    # draw hour hand 
    p.save
    p.rotate((-((time.min/60.0) + time.hour - 3.0) * 30.0))
    p.moveto(-radius/10, -radius/20)
    p.lineto(radius/2, 0.0)
    p.lineto(-radius/10, radius/20)
    p.closepath
    p.fill
    p.restore

    # draw minute hand
    p.save
    p.rotate((-((time.sec/60.0) + time.min - 15.0) * 6.0))
    p.moveto(-radius/10, -radius/20)
    p.lineto(radius * 0.8, 0.0)
    p.lineto(-radius/10, radius/20)
    p.closepath
    p.fill
    p.restore

    # draw second hand
    p.setcolor("fillstroke", "rgb", 1.0, 0.0, 0.0, 0.0)
    p.setlinewidth(2)
    p.save
    p.rotate(-((time.sec - 15.0) * 6.0))
    p.moveto(-radius/5, 0.0)
    p.lineto(radius, 0.0)
    p.stroke
    p.restore

    # draw little circle at center
    p.circle(0, 0, radius/30)
    p.fill

    p.restore
    p.end_page_ext("")
    p.end_document("")

    p.get_buffer()
  end



  def chartab_pdf
    # change these as required
    fontname = "LuciduxSans-Oblique"

    # This is where font/image/PDF input files live. Adjust as necessary.
    searchpath = "../../data"

    # list of encodings to use
    encodings = ["iso8859-1", "iso8859-2", "iso8859-15"]
    fontsize	= 16
    top		= 700
    left		= 50
    yincr	= 2*fontsize
    xincr	= 2*fontsize

    # whether or not to embed the font 
    embed = 1

    p = PDFlib.new

    if (p.begin_document("", "destination {type fitwindow page 1}") == -1)
      raise "Error: " + p.get_errmsg()
    end

    p.set_parameter("fontwarning", "true")

    p.set_parameter("SearchPath", searchpath)

    p.set_info("Creator", "chartab.rb")
    p.set_info("Author", "Thomas Merz")
    p.set_info("Title", "Character table (Ruby)")

    # loop over all encodings
    encodings.each { |encoding|
      p.begin_page_ext(595, 842, "");  # start a new page

      # print the heading and generate the bookmark 
      font = p.load_font("Helvetica", "winansi", "")
      p.setfont(font, fontsize)
      if (embed == 1)
	buf = fontname + " (" + encoding + ") embedded"
      else
	buf = fontname + " (" + encoding + ") not  embedded"
      end

      p.show_xy(buf, left - xincr, top + 3 * yincr)
      p.create_bookmark(buf, "")

      # print the row and column captions 
      p.setfont(font, 2 * fontsize/3)

      0.step(16, 1) do |row|
	buf = sprintf("x%X", row)
	p.show_xy(buf, left + row*xincr, top + yincr)

	buf = sprintf("%Xx", $row)
	p.show_xy(buf, left - xincr, top - row * yincr)
      end

      # print the character table
      if (embed == 1)
	  optlist = "embedding"
      else
	  optlist = ""
      end
      font = p.load_font(fontname, encoding, optlist)
      p.setfont(font, fontsize)

      y = top
      x = left

      0.step(16, 1) do |row|
	0.step(16,1) do |col|
	  buf = sprintf("%c", 16 * row + col)
	  p.show_xy(buf, x, y)
	  x += xincr
	end
	x = left
	y -= yincr
      end

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

    p.get_buffer()
  end

  def invoice_pdf
    infile = "stationery.pdf"
    # This is where font/image/PDF input files live. Adjust as necessary.
    searchpath = "../../data"
    left = 55
    right = 530
    fontsize = 12
    pagewidth = 595
    pageheight = 842
    baseopt =
      "ruler        {   30 45     275   375   475} " +
      "tabalignment {right left right right right} " +
      "hortabmethod ruler fontsize 12 "


    now = Time.now
    fulldate = now.strftime("%b %d, %Y")

    String      closingtext =
      "Terms of payment: <fillcolor={rgb 1 0 0}>30 days net. " +
      "<fillcolor={gray 0}>90 days warranty starting at the day of sale. " +
      "This warranty covers defects in workmanship only. " +
      "<fontname=Helvetica-BoldOblique encoding=winansi>" +
      "Kraxi Systems, Inc. " +
      "<resetfont>will, at its option, repair or replace the " +
      "product under the warranty. This warranty is not transferable. " +
      "No returns or exchanges will be accepted for wet products."

    data = [
      { "name" => "Super Kite",         "price" => 20,  "quantity" => 2},
      { "name" => "Turbo Flyer",        "price" => 40,  "quantity" => 5},
      { "name" => "Giga Trash",         "price" => 180, "quantity" => 1},
      { "name" => "Bare Bone Kit",      "price" => 50,  "quantity" => 3},
      { "name" => "Nitty Gritty",       "price" => 20,  "quantity" => 10},
      { "name" => "Pretty Dark Flyer",  "price" => 75,  "quantity" => 1},
      { "name" => "Free Gift",          "price" => 0,   "quantity" => 1}
    ]

    months = [
      "January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ]

    p = PDFlib.new

    if (p.begin_document("", "") == -1)
      print "Error: " + p.get_errmsg
    end

    p.set_parameter("SearchPath", searchpath)

    p.set_info("Creator", "invoice.rb")
    p.set_info("Author", "Thomas Merz")
    p.set_info("Title", "PDFlib invoice generation demo (Ruby)")

    stationery = p.open_pdi(infile, "", 0)
    if (stationery == -1)
      print "Error: " + p.get_errmsg
    end

    page = p.open_pdi_page(stationery, 1, "")
    if (page == -1)
      print "Error: " + p.get_errmsg
    end

    boldfont = p.load_font("Helvetica-Bold", "winansi", "")
    regularfont = p.load_font("Helvetica", "winansi", "")
    leading = fontsize + 2

    # Establish coordinates with the origin in the upper left corner.
    p.begin_page_ext(pagewidth, pageheight, "topdown")

    p.fit_pdi_page(page, 0, pageheight, "")
    p.close_pdi_page(page)

    p.setfont(regularfont, fontsize)

    # Print the address
    y = 170
    p.set_value("leading", leading)

    p.show_xy("John Q. Doe", left, y)
    p.continue_text("255 Customer Lane")
    p.continue_text("Suite B")
    p.continue_text("12345 User Town")
    p.continue_text("Everland")

    # Print the header and date

    p.setfont(boldfont, fontsize)
    y = 300
    p.show_xy("INVOICE", left, y)

    p.fit_textline(fulldate, right, y, "position {100 0}")

    # Print the invoice header line

    y = 370
    buf = "\tITEM\tDESCRIPTION\tQUANTITY\tPRICE\tAMOUNT"
    optlist = baseopt + " font " + boldfont.to_s

    textflow = p.create_textflow(buf, optlist)

    if (textflow == -1)
      print "Error: " + p.get_errmsg
    end

    p.fit_textflow(textflow, left, y-leading, right, y, "")
    p.delete_textflow(textflow)

    # Print the article list

    i = 1
    y += 2*leading
    total = 0

    optlist = baseopt + " font " + regularfont.to_s

    data.each { |row|
      sum = row["price"] * row["quantity"]
      $buf = sprintf("\t%d\t%s\t%d\t%.2f\t%.2f",
	  i, row["name"], row["quantity"], row["price"], sum);

      textflow = p.create_textflow(buf, optlist)

      if (textflow == -1)
	print "Error: " + p.get_errmsg
      end

      p.fit_textflow(textflow, left, y-leading, right, y, "")
      p.delete_textflow(textflow)

      i += 1
      y += leading
      total += sum
    }

    y += leading
    p.setfont(boldfont, fontsize)
    p.fit_textline(total.to_s, right, y, "position {100 0}")

    # Print the closing text

    y += 5*leading

    optlist = "alignment=justify leading=120% " \
	    "fontname=Helvetica fontsize=12 encoding=winansi "

    textflow = p.create_textflow(closingtext, optlist)

    if (textflow == -1)
      print "Error: " + p.get_errmsg
    end

    p.fit_textflow(textflow, left, y+6*leading, right, y, "")
    p.delete_textflow(textflow)

    p.end_page_ext("")
    p.end_document("")
    p.close_pdi(stationery)

    p.get_buffer()
  end


  def quickreference_pdf
    maxrow = 2
    maxcol = 2
    width = 500
    height = 770
    infile = "reference.pdf"
    # This is where font/image/PDF input files live. Adjust as necessary.
    searchpath = "../../data"

    p = PDFlib.new

    if (p.begin_document("", "") == -1)
      print "Error: " + p.get_errmsg()
    end

    p.set_parameter("SearchPath", searchpath)

    p.set_info("Creator", "quickreference.rb")
    p.set_info("Author", "Thomas Merz")
    p.set_info("Title", "imposition demo (Ruby)")

    manual = p.open_pdi(infile, "", 0)
    if (manual == -1)
      print "Error: " + p.get_errmsg()
    end

    row = 0
    col = 0

    p.set_parameter("topdown", "true")

    endpage = p.get_pdi_value("/Root/Pages/Count", manual, -1, 0)

    1.step(endpage, 1) do |pageno|
      if (row == 0 && col == 0)
	p.begin_page_ext(width, height, "")
	font = p.load_font("Helvetica-Bold", "winansi", "")
	p.setfont(font, 18)
	p.set_text_pos(24, 24)
	p.show("PDFlib Quick Reference")
      end

      page = p.open_pdi_page(manual, pageno, "")

      if (page == -1)
	print "Error: " + p.get_errmsg()
      end

      p.fit_pdi_page(page, width/maxcol*col,
	  (row + 1) * height/maxrow, "scale " + (1.0/maxrow).to_s)
      p.close_pdi_page(page)

      col = col + 1
      if (col == maxcol)
	col = 0
	row = row + 1
      end
      if (row == maxrow)
	row = 0
	p.end_page_ext("")
      end
    end

    # finish the last partial page
    if (row != 0 || col != 0)
      p.end_page_ext("")
    end

    p.end_document("")
    p.close_pdi(manual)

    p.get_buffer()
  end


  def businesscard_pdf
    # This is where font/image/PDF input files live. Adjust as necessary.
    #
    # Note that this directory must also contain the LuciduxSans font
    # outline and metrics files.
    infile = "boilerplate.pdf"
    searchpath = "../../data"
    data = {
      "name" =>                   "Victor Kraxi",
      "business.title" =>         "Chief Paper Officer",
      "business.address.line1" => "17, Aviation Road",
      "business.address.city" =>  "Paperfield",
      "business.telephone.voice"=>"phone +1 234 567-89",
      "business.telephone.fax" => "fax +1 234 567-98",
      "business.email" =>         "victor@kraxi.com",
      "business.homepage" =>      "www.kraxi.com"
    }

    p = PDFlib.new
    if (p.begin_document("", "") == -1)
	print "Error: " + p.get_errmsg()
    end

    # Set the search path for fonts and PDF files 
    p.set_parameter("SearchPath", searchpath)

    p.set_info("Creator", "businesscard.rb")
    p.set_info("Author", "Thomas Merz")
    p.set_info("Title", "PDFlib block processing sample (Ruby)")

    blockcontainer = p.open_pdi(infile, "", 0)
    if (blockcontainer == -1)
      print "Error: " + p.get_errmsg()
    end

    page = p.open_pdi_page(blockcontainer, 1, "")
    if (page == -1)
      print "Error: " + p.get_errmsg()
    end

    p.begin_page_ext(20, 20, "");              # dummy page size

    # This will adjust the page size to the block container's size.
    p.fit_pdi_page(page, 0, 0, "adjustpage")

    # Fill all text blocks with dynamic data
    data.each { |key, value|
      if (p.fill_textblock(page, key, value,
	  "embedding encoding=winansi") == -1)
	print "Warning: " + p.get_errmsg
      end
    }

    p.end_page_ext("")
    p.close_pdi_page(page)

    p.end_document("")
    p.close_pdi(blockcontainer)

    p.get_buffer()
  end
