package printService;

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.print.*;
import java.io.*;
import javax.print.*;
import javax.print.attribute.*;


/**
 * Program demonstrujący wykorzystanie usług drukownia z użyciem strumieni.
 * Program drukuje kształty Java 2D do pliku PostScript. Jeśli w wierszu poleceń 
 * nie zostanie podana nazwa pliku, to wyniki zostaną zapisane w pliku out.ps. 
 * @version 1.0 2018-06-01
 * @author Cay Horstmann
 */
public class PrintServiceTest
{
   // Określenie wielkości tworzonego rysunku
   private static int IMAGE_WIDTH = 300;
   private static int IMAGE_HEIGHT = 300;

   public static void draw(Graphics2D g2) 
   {
      // Kod generujący rysunek
      FontRenderContext context = g2.getFontRenderContext();
      var f = new Font("Serif", Font.PLAIN, 72);
      var clipShape = new GeneralPath();

      var layout = new TextLayout("Witaj, ", f, context);
      AffineTransform transform = AffineTransform.getTranslateInstance(0, 72);
      Shape outline = layout.getOutline(transform);
      clipShape.append(outline, false);

      layout = new TextLayout("świecie", f, context);
      transform = AffineTransform.getTranslateInstance(0, 144);
      outline = layout.getOutline(transform);
      clipShape.append(outline, false);

      g2.draw(clipShape);
      g2.clip(clipShape);

      final int NLINES = 50;
      var p = new Point2D.Double(0, 0);
      for (int i = 0; i < NLINES; i++)
      {
         double x = (2 * IMAGE_WIDTH * i) / NLINES;
         double y = (2 * IMAGE_HEIGHT * (NLINES - 1 - i)) / NLINES;
         var q = new Point2D.Double(x, y);
         g2.draw(new Line2D.Double(p, q));
      }     
   }   
   
   public static void main(String[] args) throws IOException, PrintException
   {
      String fileName = args.length > 0 ? args[0] : "out.ps";
      DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
      var mimeType = "application/postscript";
      StreamPrintServiceFactory[] factories 
         = StreamPrintServiceFactory.lookupStreamPrintServiceFactories(flavor, mimeType);
      var out = new FileOutputStream(fileName);
      if (factories.length > 0) 
      {
         PrintService service = factories[0].getPrintService(out);            
         var doc = new SimpleDoc(new Printable() 
            {
               public int print(Graphics g, PageFormat pf, int page) 
               {
                  if (page >= 1) return Printable.NO_SUCH_PAGE;
                  else 
                  {
                     double sf1 = pf.getImageableWidth() / (IMAGE_WIDTH + 1);
                     double sf2 = pf.getImageableHeight() / (IMAGE_HEIGHT + 1);
                     double s = Math.min(sf1, sf2);
                     var g2 = (Graphics2D) g;
                     g2.translate((pf.getWidth() - pf.getImageableWidth()) / 2, 
                        (pf.getHeight() - pf.getImageableHeight()) / 2);
                     g2.scale(s, s);
                   
                     draw(g2);
                     return Printable.PAGE_EXISTS;
                  }
               }
            }, flavor, null);
         DocPrintJob job = service.createPrintJob();
         var attributes = new HashPrintRequestAttributeSet();
         job.print(doc, attributes);
      } 
      else
         System.out.println("Brak obiektów fabrykujących dla typu " + mimeType);
   }
}
