package util;

import java.awt.*;
import java.awt.print.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.print.*;
import DrawTop.*;
import shape.*;

public class FileIo {
    private JFileChooser fileChooser;
    private String currentFilePath="";
    private FileInformation fileInformation=new FileInformation();
    public static int debug=0;
    
    public FileIo(){
        this.fileChooser = new JFileChooser();
        ExtensionFileFilter filter =new ExtensionFileFilter();
        filter.addExtension("draw");
        filter.setDescription("*.draw");
        this.fileChooser.setFileFilter(filter);
    }
	
    public String getCurrentFilePath(){
		return this.currentFilePath;
	}
	
    public FileInformation getFileInformation(){
		return this.fileInformation;
	}
	
    public void fileNew(){
		int ret=saveCurrentFile(); //ret: saved=0, unsaved=1, canceled=2
		if(ret==JOptionPane.YES_OPTION){
			String fileName=this.fileInformation.getSimpleFileName(this.currentFilePath);
			String message="The current file was saved as \""+fileName+"\".\n"
					+"Then a file will be opened.";
			JOptionPane.showMessageDialog(ObjectTable.getDrawMain(), message);
		}
		if(ret==JOptionPane.NO_OPTION){
			String message="The current file was not saved.\n"
					+ "Then a new file will be opened.";
			JOptionPane.showMessageDialog(ObjectTable.getDrawMain(), message);
		}
		if(ret==JOptionPane.CANCEL_OPTION) return;
		
        PageManager pageManager=new PageManager();
        ObjectTable.pageManager=pageManager;
        pageManager.init();
        this.currentFilePath="";
        DrawMain drawMain=ObjectTable.getDrawMain();
        drawMain.setTitle("DrawTop file name : "+"");
    } //fileNew
        
    public void fileOpen(){
		int ret=saveCurrentFile(); //ret: saved=0, unsaved=1, canceled=2
		if(ret==JOptionPane.YES_OPTION){
			String fileName=this.fileInformation.getSimpleFileName(this.currentFilePath);
			String message="The current file was saved as \""+fileName+"\".\n"
					+"Then the file open dialog will be opened.";
			JOptionPane.showMessageDialog(ObjectTable.getDrawMain(), message);
		}
		if(ret==JOptionPane.NO_OPTION){
			String message="The current file was not saved.\n"
					+ "Then the file open dialog will be opened.";
			JOptionPane.showMessageDialog(ObjectTable.getDrawMain(), message);
		}
		if(ret==JOptionPane.CANCEL_OPTION) return;
        if(debug>0) System.out.println("** FileIO.fileOpen called");
        DrawMain drawMain=ObjectTable.getDrawMain();
        PageManager pageManager=new PageManager();
        ObjectTable.pageManager=pageManager;
        drawMain.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        String directoryPath=this.fileInformation.getDirectory();
        if(!directoryPath.equals("")) {
            File directory=new File(directoryPath);
            this.fileChooser.setCurrentDirectory(directory);
            if(debug>0) System.out.println("** File I/O directory set="+directoryPath);
        }
        pageManager.init();
        if(fileChooser.showOpenDialog(drawMain)!=JFileChooser.APPROVE_OPTION) {
            return;
        }
        String filePath=this.fileChooser.getSelectedFile().toString();
		if(!filePath.endsWith(".draw")) filePath+=".draw";
        File file = new File(filePath);
        if (!file.isFile()) {
            String str="Draw file :"+this.fileInformation.getSimpleFileName(filePath)+
                    " not found";
            JOptionPane.showMessageDialog(ObjectTable.getDrawMain(), str, "",
                JOptionPane.ERROR_MESSAGE);
            this.currentFilePath="";
            return;
        }
        if(debug>0) System.out.println("** FileIO.fileOpen filePath="+filePath);
        this.currentFilePath=filePath;
        directoryPath=this.fileInformation.convertToDirectoryName(filePath);
        if(directoryPath!=null){
            this.fileInformation.setFileDirectory(directoryPath);
        } else{
            System.err.println("*** Error FileIO.fileOpen: \\ not found in filePath");
        }
        try{
			DrawFileIo drawFileIo=ObjectTable.getDrawFileIo();
            ArrayList newPageList=drawFileIo.readPageList(filePath);
            if(newPageList==null||newPageList.size()==0){
                this.currentFilePath="";
                return;
            }
            //pageManager=ObjectTable.getPageManager();
            pageManager.setPageList(newPageList);
            pageManager.setCurrentPage(1);
            pageManager.showPage(1);
            this.currentFilePath=filePath;
        } catch(Exception e){
            System.err.println("*** Error FileIO.fileOpen e="+e);
            e.printStackTrace();
            this.currentFilePath="";
        }
        drawMain.setTitle("DrawTop file name : "+
                this.fileInformation.getSimpleFileName(this.currentFilePath));
        drawMain.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        return;
    } //fileOpen
    
// Revised 2016.04.09
    public int fileSave(){
		DrawMain drawMain=ObjectTable.getDrawMain();
        if(this.currentFilePath.equals("")){
			int ret=fileSaveAs();
			return ret;
        }
        if(debug>0) System.out.println("** FileIO.fileSave currentFilePath="+this.currentFilePath);

        PageManager pageManager=ObjectTable.getPageManager("FileIO");
        if(debug>0) System.out.println("** FileIO.fileSave called");
        drawMain.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        try{
          //--------------------------------------------------------------------//  
            pageManager.saveCurrentPage();  //revised 2016.04,08
			//pageManager.savePageAtFileSave();  //deleted 2016.04,08
			DrawFileIo drawFileIo=ObjectTable.getDrawFileIo();
            drawFileIo.writePageList(this.currentFilePath, pageManager.getPageList());
          //--------------------------------------------------------------------// 
            if(debug>0) System.out.println("** File I/O successfull outputFile="+this.currentFilePath);
            String directory=this.fileInformation.convertToDirectoryName(this.currentFilePath);
            this.fileInformation.setFileDirectory(directory);
            drawMain.setTitle("DrawTop file name : "+this.fileInformation.getSimpleFileName(this.currentFilePath));
            if(debug>0) System.out.println("** File I/O directory set="+directory);
        } catch(Exception e){
            System.err.println("*** Error FileIO fileSave e="+e);
            e.printStackTrace();
        }   
        // Make sure chooser is updated to reflect new file
        this.fileChooser.rescanCurrentDirectory();
        drawMain.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		UndoDrawManager undoManager = ObjectTable.getUndoDrawManager();
		undoManager.discardAllEdits();
		return 0;
    }//fileSave
	
    public int fileSaveAs(){
		DrawMain drawMain=ObjectTable.getDrawMain();
		//Set the directory last opened
        String directoryPath=this.fileInformation.getDirectory();
        if(!directoryPath.equals("")) {
            File directory=new File(directoryPath);
            this.fileChooser.setCurrentDirectory(directory);
        }
        String filePath="";
		int ret=this.fileChooser.showSaveDialog(drawMain);
		//JFileChooser.APPROVE_OPTION:Yes/Ok, CANCEL_OPTION:Cancel
        if(ret==JFileChooser.CANCEL_OPTION) return 1;
        filePath = this.fileChooser.getSelectedFile().toString();
        if(!filePath.endsWith(".draw")) filePath+=".draw";
        directoryPath=this.fileInformation.convertToDirectoryName(filePath);
        if(!directoryPath.equals("")){
            if(debug>0) System.out.println("** FileIO.fileSaveAs filePath="+filePath+
                        "\n   fileDirectory="+directoryPath);
                this.fileInformation.setFileDirectory(directoryPath);
        } else{
                System.err.println("  Error \\ not found in filePath");
        }
		
        PageManager pageManager=ObjectTable.getPageManager("FileIO");
        if(debug>0) System.out.println("** FileIO.fileSaveAs called");
        drawMain.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        try{
          //--------------------------------------------------------------------//  
            pageManager.saveCurrentPage();  //revised 2016.04,08
			//pageManager.savePageAtFileSave();
			DrawFileIo drawFileIo=ObjectTable.getDrawFileIo();
            drawFileIo.writePageList(filePath, pageManager.getPageList());
          //--------------------------------------------------------------------//  
            this.currentFilePath=filePath;
            drawMain.setTitle("DrawTop file name : "+this.fileInformation.getSimpleFileName(filePath));
            if(debug>0)System.out.println("*** File I/O successfull outputFile="+filePath);
        } catch(Exception e){
            System.err.println("*** Error: FileIO.fileSaveAs, e="+e);
            e.printStackTrace();
        }
        this.fileChooser.rescanCurrentDirectory();
        drawMain.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		UndoDrawManager undoManager = ObjectTable.getUndoDrawManager();
		undoManager.discardAllEdits();
		return 0;
    }//fileSave
    
	public int saveCurrentFile(){
		int ret=0;
		ContainerManager containerManager = ObjectTable.getContainerManager();
		UndoDrawManager undoManager = ObjectTable.getUndoDrawManager();
		int size=containerManager.size();
		boolean undo=undoManager.canUndo();
		if(debug>0) System.out.println("** FileIO.saveCurrentFile size="+size+", undo="+undo);
		if(size==0||!undo) {
			return -1;
		} 
		String fileName=this.fileInformation.getSimpleFileName(this.currentFilePath);
		String message;
		if(fileName.equals("")) message = "The current nameless file was changed.";
		else message = "The \""+fileName+"\" current file was changed.";
		message+=" Do you want to save it?";
		ret=JOptionPane.showConfirmDialog(ObjectTable.getDrawMain(), message, "", 
				JOptionPane.YES_NO_CANCEL_OPTION);
		//ret: JOptionPane.YES_OPTION=0, JOptionPane.NO_OPTION)=1, JOptionPane.CANCEL_OPTION=2
		if(ret==JOptionPane.CLOSED_OPTION) ret=JOptionPane.CANCEL_OPTION;
		if(debug>0) System.out.println("** FileIO.currentfileSaved ret1="+ret);
		//if(ret!=0) return ret;
		if(ret==JOptionPane.NO_OPTION) return 1;
		if(ret==JOptionPane.CANCEL_OPTION) return 2;

        // File save action
		if(fileName.equals("")){
			fileSaveAs();
		} else {
			fileSave();
		}
		return 0;
	}
	
    public void printOut(){
        PrinterJob printerJob = PrinterJob.getPrinterJob();
        PrintService[] printerServices=printerJob.lookupPrintServices();
        if(printerServices==null||printerServices.length==0){
            JOptionPane.showMessageDialog(ObjectTable.getDrawMain(),
                    "Printer not found");
            return;
        }
        Book book=this.createBook();
        printerJob.setPageable(book);
        if (printerJob.printDialog()) {
            try {
                printerJob.print();
            } catch (Exception PrintException) {
                PrintException.printStackTrace();
            }
        }
    }
    
    public Book createBook() {
        PageManager pageManager=ObjectTable.getPageManager("FileIO");
        Book book=new Book();
        int numOfPages=pageManager.getPageList().size();
        for(int i=0;i<numOfPages;i++){
            ViewData viewData=pageManager.getViewData(i+1);
            int sheetSize=viewData.getSheetSize();
            Dimension sheetDimension=DrawParameters.SheetSizesMM[sheetSize];
            double pixels=72d/DrawParameters.InchToMM;
            sheetDimension=new Dimension((int)(sheetDimension.getWidth()*pixels), 
                (int)(sheetDimension.getHeight()*pixels));
            PageFormat pageFormat=new PageFormat();
            pageFormat.setOrientation(PageFormat.PORTRAIT);
            double paperWidth=sheetDimension.getWidth();
            double paperHeight=sheetDimension.getHeight();
            if(viewData.getSheetOrientation()==DrawParameters.LandScape) {
                pageFormat.setOrientation(PageFormat.LANDSCAPE);
            }
            double marginLeft=0d; 
            double marginRight=0d;
            double marginUpper=0d; 
            double marginBottom=0d; 
            double originX=marginLeft; 
            double originY=marginUpper;
            double imagenableWidth=paperWidth-marginLeft-marginRight;
            double imagenableHeight=paperHeight-marginUpper-marginBottom;
            Paper paper=new Paper();
            paper.setSize(paperWidth, paperHeight);
            paper.setImageableArea(originX, originY, imagenableWidth, imagenableHeight);
            pageFormat.setPaper(paper);
            if(debug>0) System.out.println("** printOut.pageFormat; " +
                    "pageFormat width,height="+pageFormat.getWidth()+","+pageFormat.getHeight()+
                    ", orientation="+pageFormat.getOrientation()+
                    ", paper width,height="+paper.getWidth()+","+paper.getHeight());
            book.append(new PrintableDrawPage(i+1), pageFormat);
        }
        return book;
    }
    
    public void exit(){
        System.exit(0);
    }

    public String getCurrentFileName(){
        return this.currentFilePath;
    }
    
    public String getCurrentSimpleFileName(){
        return this.fileInformation.getSimpleFileName(this.currentFilePath);
    }
    
    public int getCurrentPage(){
        return ObjectTable.getPageManager().getCurrentPage();
    }
    
} //End of FileIo
