/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package git;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import static java.awt.print.Printable.NO_SUCH_PAGE;
import static java.awt.print.Printable.PAGE_EXISTS;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import jpos.FiscalPrinter;
import jpos.JposException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

/**
 *
 * @author Fabio
 */
public class Order {
    private Menu menuItem = null;
    //private MenuItem menuItem = null;
    private int id = -1;
    private final String USER_AGENT = "Mozilla/5.0";
    private int maxLength = 27;
    private String fileName = "ticket_printer.txt";
    private boolean printTicket = true;
    private boolean printReceipt = true;
    private String fileNameDomain = "domain.txt";
    private String domain = "http://virtualbeach.gitgrado.it";
    
    public Order(final int id, final int action){
        this.id = id;
        
        String lineDomain = null;

        try {
            // FileReader reads text files in the default encoding.
            FileReader fileReader = 
                new FileReader(fileNameDomain);

            // Always wrap FileReader in BufferedReader.
            BufferedReader bufferedReader = 
                new BufferedReader(fileReader);

            while((lineDomain = bufferedReader.readLine()) != null) {
                if(lineDomain.length() > 0){
                    domain = lineDomain;
                }
                System.out.println(lineDomain);
            }   

            // Always close files.
            bufferedReader.close();         
        }
        catch(FileNotFoundException ex) {
            System.out.println(
                "Unable to open file '" + 
                fileNameDomain + "'");                
        }
        catch(IOException ex) {
            System.out.println(
                "Error reading file '" 
                + fileNameDomain + "'");                  
            // Or we could just do this: 
            // ex.printStackTrace();
        }
        
        menuItem = new Menu(id+"");
        if(action == 2 || action == 3){
            //menuItem = new MenuItem(id+"");
            MenuItem receiptItem = new MenuItem("Receipt");
            menuItem.add(receiptItem);
            receiptItem.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JFrame frame = new JFrame("My dialog asks....");

                    frame.setUndecorated( true );
                    frame.setVisible( true );
                    frame.setLocationRelativeTo( null );


                    int confirm = JOptionPane.showOptionDialog(frame,
                            "Are You Sure to Print the Receipt for Order "+id+"?",
                            "Print Confirmation", JOptionPane.YES_NO_OPTION,
                            JOptionPane.QUESTION_MESSAGE, null, null, null);
                    if (confirm == JOptionPane.YES_OPTION) {
                        printTicket = false;
                        printReceipt = true;
                        printOrder();
                    }

                    frame.dispose();

                }

            });
        }
        
        if(action == 1 || action == 3){
            //menuItem = new MenuItem(id+"");
            MenuItem ticketItem = new MenuItem("Ticket");
            menuItem.add(ticketItem);
            ticketItem.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JFrame frame = new JFrame("My dialog asks....");

                    frame.setUndecorated( true );
                    frame.setVisible( true );
                    frame.setLocationRelativeTo( null );


                    int confirm = JOptionPane.showOptionDialog(frame,
                            "Are You Sure to Print the Ticket for Order "+id+"?",
                            "Print Confirmation", JOptionPane.YES_NO_OPTION,
                            JOptionPane.QUESTION_MESSAGE, null, null, null);
                    if (confirm == JOptionPane.YES_OPTION) {
                        printReceipt = false;
                        printTicket = true;
                        printOrder();
                    }

                    frame.dispose();

                }

            });
        }
    }
    
    public MenuItem getMenuItem(){
        return menuItem;
    }
    
    public int getId(){
        return id;
    }
    
    public void printOrder(){
        try {
            String toPrint = "";
            String jsonResponse = getOrderRows();
            JSONObject jsonObject = (JSONObject) new JSONTokener(jsonResponse).nextValue();
            JSONArray orderRows = jsonObject.getJSONArray("order_rows");
            JSONArray ticketDescription = jsonObject.getJSONArray("ticket_descriptions");
            boolean isReceipt = jsonObject.getBoolean("is_receipt");
            if(!printReceipt){
                isReceipt = false;
            }
            int ticketsNumber = jsonObject.getInt("tickets_number");
            toPrint += splitRow("G.I.T. S.P.A. Spiaggia", maxLength);
            toPrint += splitRow("Tel.: 0432-899220", maxLength);
            toPrint += splitRow("----------------------", maxLength);
            toPrint += splitRow("NOMINATIVO: "+jsonObject.getString("customer_name"), maxLength);
            toPrint += splitRow("CODICE PRENOTAZIONE: "+jsonObject.getInt("order_number"), maxLength);
            toPrint += splitRow("DATA EMISSIONE: "+jsonObject.getString("order_date"), maxLength);
            toPrint += '\n';
            FiscalPrinter printer = new FiscalPrinter();
            if(isReceipt){

                try
                {
                   //Open Printer
                   printer.open("EthernetFiscalPrinter");
                   printer.claim(1);
                   printer.setDeviceEnabled(true);
                   
                   System.out.println("METODI PAGAMENTO: *"+printer.getPredefinedPaymentLines()+"*");

                   printer.beginFiscalReceipt(true);
                }
                catch(JposException e)
                {
                    // display any errors that come up
                    JFrame frame = new JFrame("My dialog asks....");

                    frame.setUndecorated( true );
                    frame.setVisible( true );
                    frame.setLocationRelativeTo( null );

                    JOptionPane.showMessageDialog(frame, "Carta stampante Fiscale esaurita");
                    frame.dispose();
                    
                    e.printStackTrace();
                    /*isReceipt = false;
                    try
                    {
                        printer.endFiscalReceipt(true);
                    }
                    catch (Exception exc) {}
                    try
                    {
                        printer.setDeviceEnabled(false);
                    }
                    catch (Exception exc) {}
                    try
                    {
                        printer.release();
                    }
                    catch (Exception exc) {}
                    try
                    {
                        printer.close();
                    }
                    catch (Exception exc) {}*/
                }
            }
            for(int i=0; i<ticketDescription.length(); i++){
                if(!ticketDescription.getJSONObject(i).getString("map_id").equals("")){
                    toPrint += splitRow(ticketDescription.getJSONObject(i).getString("list_object_name")+": ", maxLength);
                    toPrint += splitRow(ticketDescription.getJSONObject(i).getString("date_start")+" - "+ticketDescription.getJSONObject(i).getString("date_end"), maxLength);
                    toPrint += splitRow("  ---  "+ticketDescription.getJSONObject(i).getString("map_label")+"  ---", maxLength);
                    toPrint += splitRow("---------------------------\n", maxLength);
                }else if(!ticketDescription.getJSONObject(i).getString("sector_id").equals("")){
                    toPrint += splitRow(ticketDescription.getJSONObject(i).getString("list_object_name")+": ", maxLength);
                    toPrint += splitRow(ticketDescription.getJSONObject(i).getString("date_start")+" - "+ticketDescription.getJSONObject(i).getString("date_end"), maxLength);
                    toPrint += splitRow("  ---  "+ticketDescription.getJSONObject(i).getString("sector_label")+"  ---", maxLength);
                    toPrint += splitRow("---------------------------\n", maxLength);
                }else{
                    toPrint += splitRow(ticketDescription.getJSONObject(i).getString("list_object_name"), maxLength);
                    toPrint += splitRow("---------------------------\n", maxLength);
                }
            }
            
            for(int i=0; i<orderRows.length(); i++){
                //System.out.println(orderRows.getJSONObject(i).getInt("id"));
                //System.out.println(orderRows.getJSONObject(i).getString("order_rows_detailed_description"));
                /*String tmpToPrint = jsonArray.getJSONObject(i).getString("order_rows_detailed_description");
                while(tmpToPrint.length() > 35){
                    toPrint += "\n"+tmpToPrint.substring(0, 35);
                    tmpToPrint = tmpToPrint.substring(35);
                }
                toPrint += "\n"+tmpToPrint+"\n";*/
                
                if(isReceipt){
                    try{
                        String tmpRow = orderRows.getJSONObject(i).getString("order_rows_detailed_description");
                        while( tmpRow.length() > 0 ){
                            if(tmpRow.length() >= 41){
                                printer.printRecMessage(tmpRow.substring(0, 41));
                                tmpRow = tmpRow.substring(41);
                            }else{
                                printer.printRecMessage(tmpRow);
                                break;
                            }
                        }
                    }
                    catch (Exception ex) {
                        
                        JFrame frame = new JFrame("My dialog asks....");

                        frame.setUndecorated( true );
                        frame.setVisible( true );
                        frame.setLocationRelativeTo( null );

                        JOptionPane.showMessageDialog(frame, "Carta stampante Fiscale esaurita");
                        frame.dispose();
                        
                        ex.printStackTrace();
                        i -= 1;
                        continue;
                        /*isReceipt = false;
                        try
                        {
                            printer.endFiscalReceipt(true);
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.setDeviceEnabled(false);
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.release();
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.close();
                        }
                        catch (Exception exc) {}*/
                        
                    }
                        //printer.printRecMessage(splitRowReceipt(orderRows.getJSONObject(i).getString("order_rows_description"), 22));
                        //printer.printRecItem(splitRowReceipt(orderRows.getJSONObject(i).getString("order_rows_description"), 22), 
                        // description price quantity, vatInfo,unitPrice,unitName
                    try{
                        printer.printRecItem(orderRows.getJSONObject(i).getString("order_rows_chart_of_accounts_name"), 
                                                (int)(orderRows.getJSONObject(i).getDouble("order_rows_price")*100), 
                                                /*(int)(orderRows.getJSONObject(i).getDouble("order_rows_qta")*/1000/*)*/, 
                                                Integer.parseInt(orderRows.getJSONObject(i).getString("order_rows_chart_of_accounts_print_code")), 
                                                (int)(orderRows.getJSONObject(i).getDouble("order_rows_price")*100), 
                                                "");
                    }
                    catch (Exception ex) {
                        
                        JFrame frame = new JFrame("My dialog asks....");

                        frame.setUndecorated( true );
                        frame.setVisible( true );
                        frame.setLocationRelativeTo( null );

                        JOptionPane.showMessageDialog(frame, "Carta stampante Fiscale esaurita");
                        frame.dispose();
                        
                        ex.printStackTrace();
                        //i -= 1;
                        /*isReceipt = false;
                        try
                        {
                            printer.endFiscalReceipt(true);
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.setDeviceEnabled(false);
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.release();
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.close();
                        }
                        catch (Exception exc) {}*/
                        
                    }
                }
            }
            if(isReceipt){
                int total = (int)(jsonObject.getDouble("order_details_amount")*100);
                int paid = (int)(jsonObject.getDouble("order_details_amount_paid")*100);
                String paymentMethod = jsonObject.getString("order_details_payment");
                try{
                    
                    printer.printRecTotal(total, 0, paymentMethod);
                    //printer.printRecTotal(total, paid, "Pagamento");
                    printer.endFiscalReceipt(true);

                    //Close Printer
                    printer.setDeviceEnabled(false);
                    printer.release();
                    printer.close();
                }
                    catch (Exception ex) {
                        
                        JFrame frame = new JFrame("My dialog asks....");

                        frame.setUndecorated( true );
                        frame.setVisible( true );
                        frame.setLocationRelativeTo( null );

                        JOptionPane.showMessageDialog(frame, "Carta stampante Fiscale esaurita");
                        frame.dispose();
                        
                        ex.printStackTrace();
                        isReceipt = false;
                        try{
                            printer.printRecTotal(total, 0, paymentMethod);
                        }catch (Exception exc) {}
                        try
                        {
                            printer.endFiscalReceipt(true);
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.setDeviceEnabled(false);
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.release();
                        }
                        catch (Exception exc) {}
                        try
                        {
                            printer.close();
                        }
                        catch (Exception exc) {}
                    }
            }
            for(int i=0; i<ticketsNumber; i++){
                if(ticketsNumber>1 && ticketsNumber-1 == i){
                    toPrint = "COPIA PER IL BAGNINO\n\n"+toPrint;
                    
                    System.out.println("************************");
                    System.out.println(toPrint);
                    System.out.println("************************");
                    
                    if(printTicket){
                        new DoPrint(toPrint);
                    }
                }else{
                    System.out.println("************************");
                    System.out.println(toPrint);
                    System.out.println("************************");
                    
                    if(printTicket){
                        new DoPrint(toPrint);
                    }
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(Order.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
   
    private String splitRow(String row, int length){
        String result = "";
        while(row.length() > length){
            if(result.length() == 0){
                result += row.substring(0, length);
            }else{
                result += "\n"+row.substring(0, length);
            }
            row = row.substring(length);
        }
        if(result.length() == 0){
            result += row+"\n";
        }else{
            result += "\n"+row+"\n";
        }
        return result;
    }
    
    private String splitRowReceipt(String row, int length){
        String result = "";
        while(row.length() > length){
            if(result.length() == 0){
                result += row.substring(0, length);
            }else{
                result += "\n"+row.substring(0, length);
            }
            row = row.substring(length);
        }
        if(result.length() == 0){
            result += row+"\n";
        }else{
            result += "\n"+row+"\n";
        }
        return result;
    }
    
    private String getOrderRows() throws Exception {

            //String url = "http://virtualbeach.homelinux.net/orders/order-rows";
            //String url = "http://virtualbeach.gitgrado.it/orders/order-rows";
            //String url = "http://test-virtualbeach.homelinux.net/orders/order-rows";
            String url = domain+"/orders/order-rows";
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();

            //add reuqest header
            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", USER_AGENT);
            con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");



            String urlParameters = "order_id="+id;

            // Send post request
            con.setDoOutput(true);
            DataOutputStream wr = new DataOutputStream(con.getOutputStream());
            wr.writeBytes(urlParameters);
            wr.flush();
            wr.close();

            int responseCode = con.getResponseCode();
            System.out.println("\nSending 'POST' request to URL : " + url);
            System.out.println("Post parameters : " + urlParameters);
            System.out.println("Response Code : " + responseCode);

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
            }
            in.close();

            //print result
            System.out.println(response.toString());
            return response.toString();
	}
    
    
    class DoPrint{
       public DoPrint(String message){
           System.out.println(message);
           PrinterJob pj = PrinterJob.getPrinterJob();

    PageFormat pf = pj.defaultPage();
    /*Paper paper = new Paper();
    //;
    paper.setSize(300, countReturns(message)*15);
    double margin = 9;
    paper.setImageableArea(margin, margin, paper.getWidth() - margin * 2, paper.getHeight()
        - margin * 2);
    pf.setPaper(paper);*/

    pj.setPrintable(new MyPrintable(message), pf);
    
    PrintService[] service = PrinterJob.lookupPrintServices(); // list of printers
    String printerNameDesired = "Custom KUBE 80mm (200dpi)";
    //String printerNameDesired = "Carta Bianca (Parco Acquatico) 17";
    
    String line = null;
    try {
            // FileReader reads text files in the default encoding.
            FileReader fileReader = 
                new FileReader(fileName);

            // Always wrap FileReader in BufferedReader.
            BufferedReader bufferedReader = 
                new BufferedReader(fileReader);

            while((line = bufferedReader.readLine()) != null) {
                if(line.length() > 0){
                    printerNameDesired = line;
                    System.out.println("Printer: "+line);
                }
            }   

            // Always close files.
            bufferedReader.close();         
        }
        catch(FileNotFoundException ex) {
            try {
                // Assume default encoding.
                FileWriter fileWriter =
                    new FileWriter(fileName);

                // Always wrap FileWriter in BufferedWriter.
                BufferedWriter bufferedWriter =
                    new BufferedWriter(fileWriter);
                    bufferedWriter.write("Custom KUBE 80mm (200dpi)");

                // Always close files.
                bufferedWriter.close();
            }
            catch(IOException exc) {
                System.out.println(
                    "Error writing to file '"
                    + fileName + "'");
                // Or we could just do this:
                // ex.printStackTrace();
            }
        }
        catch(IOException ex) {
            System.out.println(
                "Error reading file '" 
                + fileName + "'");                  
            // Or we could just do this: 
            // ex.printStackTrace();
        }
    
    int count = service.length;
    DocPrintJob docPrintJob = null;
    for (int i = 0; i < count; i++) {
        if (service[i].getName().equalsIgnoreCase(printerNameDesired)) {
            docPrintJob = service[i].createPrintJob();
            i = count;
        }
    }
    
    //if (pj.printDialog()) {
    try {
        pj.setPrintService(docPrintJob.getPrintService());
        pj.print();
      } catch (PrinterException e) {
          
            JFrame frame = new JFrame("My dialog asks....");

            frame.setUndecorated( true );
            frame.setVisible( true );
            frame.setLocationRelativeTo( null );

            JOptionPane.showMessageDialog(frame, "Carta stampante Ticket esaurita");
            frame.dispose();
          
          e.printStackTrace();
        System.out.println(e);
        
      }
    //}
       }
   }
    
    public static int countReturns(String str){
        String findStr = "\n";
        int lastIndex = 0;
        int count = 0;

        while(lastIndex != -1){

            lastIndex = str.indexOf(findStr,lastIndex);

            if(lastIndex != -1){
                count ++;
                lastIndex += findStr.length();
            }
        }
        System.out.println(count);
        return count;
    }
   
   class MyPrintable implements Printable {
  String str;
  public MyPrintable(String getStr)
  {
     str = getStr;
  }
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    if (pageIndex != 0)
      return NO_SUCH_PAGE;
    Graphics2D g2 = (Graphics2D) g;
    g2.setFont(new Font("monospaced", Font.BOLD, 10));
    g2.setPaint(Color.black);
    int x = 50;
    /*int y = 5;
    for (String line : str.split("\n"))
        g.drawString(line, x, y += g.getFontMetrics().getHeight());
    Rectangle2D outline = new Rectangle2D.Double(pf.getImageableX(), pf.getImageableY(), pf
        .getImageableWidth(), pf.getImageableHeight());*/
    int y = (int)pf.getImageableY();
    int numLines = 0;
    for (String line : str.split("\n")){
        numLines += 1;
        g.drawString(line, x, y += g.getFontMetrics().getHeight());
    }
    Rectangle2D outline = new Rectangle2D.Double(pf.getImageableX(), pf.getImageableY(), pf
        .getImageableWidth(), numLines*15);
    g2.draw(outline);
    return PAGE_EXISTS;
  }
}
}
