/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eric;

import eric.GUI.palette.PaletteManager;
import eric.GUI.pipe_tools;
import eric.GUI.themes;
import eric.GUI.window.ImageFilter;
import eric.GUI.window.LeftPanel;
import eric.GUI.window.MainWindow;
import eric.GUI.window.Open_left_panel_btn;
import eric.GUI.window.Open_middle_panel_btn;
import eric.GUI.window.Open_right_panel_btn;
import eric.GUI.window.RightPanel;
import eric.GUI.window.tab_btn;
import eric.GUI.window.tab_main_panel;
import eric.GUI.windowComponent;
import eric.bar.JPropertiesBar;
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Image;
import java.awt.datatransfer.Clipboard;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileSystemView;
import rene.dialogs.Warning;
import rene.gui.Global;
import rene.util.FileName;
import rene.util.ImageSelection;
import rene.util.PngEncoder;
import rene.util.xml.XmlTag;
import rene.zirkel.ZirkelCanvas;
import rene.zirkel.ZirkelFrame;
import rene.zirkel.construction.Count;
import rene.zirkel.graphics.MyGraphicsEPS;
import rene.zirkel.graphics.MyGraphicsSvg;

/**
 *
 * @author erichake
 */
public class FileTools {

    static private int dlogW=500;
    static private int dlogH=400;
    static private ArrayList<String> StartupFiles=new ArrayList<String>();
    static private boolean isStartup=true;

    public static void addStartupFile(String filename) {
        StartupFiles.add(filename);
    }

    public static boolean isStartup() {
        return isStartup;
    }

    public static String getCurrentFileSource() throws Exception {
        ZirkelCanvas zc=JZirkelCanvas.getCurrentZC();
        final ByteArrayOutputStream out=new ByteArrayOutputStream();
        zc.save(out, true, true, false, true, zc.getMacros(), "");
        return out.toString("utf-8");
    }

    public static void setCurrentFileSource(String s) throws Exception {
        final ZirkelCanvas zc=JZirkelCanvas.getCurrentZC();
        final ByteArrayOutputStream bout=new ByteArrayOutputStream();
        final PrintWriter out=new PrintWriter(new OutputStreamWriter(
                bout, "utf-8"));
        out.print(s);
        out.close();
        final byte b[]=bout.toByteArray();
        final InputStream in=new ByteArrayInputStream(b);
        zc.clear();
        zc.removeAllScripts();
        Count.resetAll();
        zc.clearDrawings();
        zc.load(in, true, true);
        zc.validate();
        zc.repaint();
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                zc.JCM.readXmlTags();
            }
        });
    }

    /*********************************************
     * Simple file part : open and save zir files
     *********************************************/
    public static void HTMLWorkBookExport() {
        String str;
        String content="";

        if (!JZirkelCanvas.isWorkBook()) {
            saveWorkBookAs();
        }
        ;

        if (JZirkelCanvas.isWorkBook()) {
            saveWorkBook(JZirkelCanvas.getWorkBookFileName());
            String targetpath=FileName.path(JZirkelCanvas.getWorkBookFileName());
            String sep=System.getProperty("file.separator");
            BufferedReader in;
            try {
                InputStream input=FileTools.class.getResourceAsStream("/eric/docs/applet.html");
                in=new BufferedReader(new InputStreamReader(input));
                while ((str=in.readLine())!=null) {
                    content+=str+"\n";
                }
                in.close();
            } catch (final Exception e) {
                return;
            }
            content=content.replace("@width@", ""+(pipe_tools.getWindowSize().width-2*themes.getVerticalBorderWidth()));
            content=content.replace("@height@", ""+(pipe_tools.getWindowSize().height-themes.getMenuBarHeight()-themes.getTitleBarHeight()));
            content=content.replace("@file@", FileName.filename(JZirkelCanvas.getWorkBookFileName()));
            content=content.replace("@workbook@", FileName.filename(JZirkelCanvas.getWorkBookFileName()));
            try {
                File aFile=new File(targetpath+sep+"index.html");
                Writer output=new BufferedWriter(new FileWriter(aFile));
                output.write(content);
                output.close();
            } catch (Exception e) {
            }
        }
    }

    public static void SaveJarAndLaunchBrowser() {

        JZirkelCanvas jzc=JZirkelCanvas.getCurrentJZF();
        if (jzc==null) {
            return;
        }
        if (JZirkelCanvas.getFileName()==null) {
            return;
        }
        String targetpath=FileName.path(JZirkelCanvas.getFileName());
        String targetfile="index.html";

        final String sep=System.getProperty("file.separator");
        final String mypath=Global.AppPath();
        if (new File(mypath+"CaRMetal.jar").exists()) {
            try {
                final InputStream in=new FileInputStream(mypath+"CaRMetal.jar");
                final OutputStream out=new FileOutputStream(targetpath+sep+"CaRMetal.jar");
                final byte[] buf=new byte[1024];
                int len;
                while ((len=in.read(buf))>0) {
                    out.write(buf, 0, len);
                    out.flush();
                }
                out.close();
                in.close();

                JBrowserLauncher.openURL(targetpath+sep+targetfile);

            } catch (final Exception ex) {
            }
        }
    }

    public static String getSwingOpenFile() {
        String name=null;
        final JFileChooser jfc=new JFileChooser(Global.getOpenSaveDirectory());
        jfc.setDialogType(javax.swing.JFileChooser.OPEN_DIALOG);
        jfc.setAcceptAllFileFilterUsed(false);
        JFileFilter filter=new JFileFilter(Global.Loc("filedialog.allfiles"), ".zirs,.zir,.zirz,.mcr,.job,.js");
        jfc.addChoosableFileFilter(filter);
        jfc.setFileFilter(filter);
        filter=new JFileFilter(Global.Loc("filedialog.filefilter"), ".zir");
        jfc.addChoosableFileFilter(filter);
        filter=new JFileFilter(Global.Loc("filedialog.workbook"), ".zirs");
        jfc.addChoosableFileFilter(filter);
        filter=new JFileFilter(Global.Loc("filedialog.compressedfilefilter"), ".zirz");
        jfc.addChoosableFileFilter(filter);
        filter=new JFileFilter(Global.Loc("filedialog.macrofilefilter"), ".mcr");
        jfc.addChoosableFileFilter(filter);
        filter=new JFileFilter(Global.Loc("filedialog.job"), ".job");
        jfc.addChoosableFileFilter(filter);
        filter=new JFileFilter(Global.Loc("filedialog.js"), ".js");
        jfc.addChoosableFileFilter(filter);
        final int rep=jfc.showOpenDialog(pipe_tools.getFrame());
        if (rep==JFileChooser.APPROVE_OPTION) {
            name=jfc.getSelectedFile().getAbsolutePath();
            Global.setOpenSaveDirectory(FileName.path(name));
        }
        return name;
    }

    public static String getAWTOpenFile() {
        String name="";
        FileDialog fd=new FileDialog(pipe_tools.getFrame(),
                Global.Loc("filedialog.open"),
                FileDialog.LOAD);
        fd.setFilenameFilter(new FilenameFilter() {

            public boolean accept(File dir, String name) {
                return (name.endsWith(".js")||name.endsWith(".mcr")||name.endsWith(".zir")||name.endsWith(".zirs")||name.endsWith(".zirz")||name.endsWith(".job")||name.endsWith(".jobz"));
            }
        });
        fd.setDirectory(Global.getOpenSaveDirectory());
        fd.setSize(dlogW, dlogH);
        fd.pack();
        fd.setVisible(true);
        if (fd.getFile()!=null) {
            Global.setOpenSaveDirectory(fd.getDirectory());
        }
        return canonicFileName(fd);
    }

    public static String getOpenFile() {
        if (OS.isUnix()) {
            return getSwingOpenFile();
        } else {
            return getAWTOpenFile();
        }
    }

    public static String getSwingSaveFile() {
        String name=null;
        final JFileChooser jfc=new JFileChooser(Global.getOpenSaveDirectory());
        jfc.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
        jfc.setAcceptAllFileFilterUsed(false);
        JFileFilter filter=new JFileFilter(Global.Loc("filedialog.allfiles"), ".zirs,.zir,.zirz,.mcr,.job");
        jfc.addChoosableFileFilter(filter);
        jfc.setFileFilter(filter);
        final int rep=jfc.showSaveDialog(pipe_tools.getFrame());
        if (rep==JFileChooser.APPROVE_OPTION) {
            name=jfc.getSelectedFile().getAbsolutePath();
            Global.setOpenSaveDirectory(FileName.path(name));
        }
        return name;
    }

    public static String getAWTSaveFile() {
        String name="";
        FileDialog fd=new FileDialog(pipe_tools.getFrame(),
                Global.Loc("filedialog.save"),
                FileDialog.SAVE);
        fd.setFilenameFilter(new FilenameFilter() {

            public boolean accept(File dir, String name) {
                return (name.endsWith(".js")||name.endsWith(".mcr")||name.endsWith(".zir")||name.endsWith(".zirs")||name.endsWith(".zirz")||name.endsWith(".job")||name.endsWith(".jobz"));
            }
        });
        fd.setDirectory(Global.getOpenSaveDirectory());
        fd.setSize(dlogW, dlogH);
        fd.pack();
        fd.setVisible(true);
        if (fd.getFile()!=null) {
            Global.setOpenSaveDirectory(fd.getDirectory());
        }
        return canonicFileName(fd);
    }

    public static String getSaveFile() {
        if (OS.isUnix()) {
            return getSwingSaveFile();
        } else {
            return getAWTSaveFile();
        }
    }

    public static String canonicFileName(FileDialog fd) {
        if (fd.getFile()==null) {
            return null;
        }
        String path=(fd.getDirectory().endsWith(System.getProperty("file.separator")))?fd.getDirectory():fd.getDirectory()+System.getProperty("file.separator");
        path+=fd.getFile();
        return path;
    }

    public static boolean validPreferencesFileName(String name) {
        return name.endsWith("preferences.txt");
    }

    public static boolean validZirkelFileName(String name) {
        String nme=name.toLowerCase();
        return (nme.endsWith(".zir")||nme.endsWith(".zirz")||nme.endsWith(".job")||nme.endsWith(".jobz"));
    }

    public static boolean validImageFileName(String name) {
        String nme=name.toLowerCase();
        return (nme.endsWith(".tif")||nme.endsWith(".tiff")||nme.endsWith(".gif")||nme.endsWith(".png")||nme.endsWith(".jpg")||nme.endsWith(".jpeg"));
    }

    public static void openFile() {
        final String filename=getOpenFile();
        if (filename!=null) {
            if (filename.endsWith(".zirs")) {
                openWorkBook(filename);
            } else if (filename.endsWith(".mcr")) {
                openMacro(filename);
            } else {
                openFile(filename, null, false);
            }
        }
    }

    public static void doLoad(final String filename, final InputStream in, final boolean with3D) {
        JZirkelCanvas JZF=JZirkelCanvas.getCurrentJZF();
        ZirkelFrame ZF=JZirkelCanvas.getCurrentZF();
        final ZirkelCanvas ZC=JZirkelCanvas.getCurrentZC();
        if (ZC!=null) {
            ZC.set3D(with3D);
            ZF.setinfo("save");
            ZC.getConstruction().BackgroundFile=null;
            ZF.Background="";
            ZC.grab(false);
            rene.zirkel.construction.Count.resetAll();
            ZF.doload(filename, in);
            PaletteManager.fix3Dpalette();
            ZC.getLocalPreferences();
            rene.zirkel.construction.Count.resetAll();

            pipe_tools.setWindowComponents();
            SwingUtilities.invokeLater(new Runnable() {

                public void run() {
                    ZC.JCM.readXmlTags();
                    PaletteManager.refresh();
                    PaletteManager.setSelected_with_clic("move", true);
                }
            });
        }
    }

    public static void openMacro(final String filename) {
        try {

            FileInputStream o=new FileInputStream(filename);
            JZirkelCanvas.getCurrentZC().load(o, false, true);
            o.close();
        } catch (Exception ex) {
        }
        JZirkelCanvas.ActualiseMacroPanel();
    }

    public static void openFile(final String filename, final InputStream in, final boolean with3D) {
        if (JZirkelCanvas.getCurrentZC()==null) {
            return;
        }
        if (filename==null) {
            return;
        }
        if ((filename.endsWith(".zir"))||(filename.endsWith(".zirz"))) {
            if (JZirkelCanvas.getCurrentZC().isEmpty()) {
                tab_main_panel.setCurrentTabName(FileName.filename(filename), filename);

            } else {
                tab_main_panel.createTabAndCanvas(FileName.filename(filename), filename);
            }
        }
        doLoad(filename, in, with3D);
        JZirkelCanvas.getCurrentJZF().setComments();
        JZirkelCanvas.ActualiseMacroPanel();

    }

    public static void New3DWindow() {
        final InputStream o=FileTools.class.getResourceAsStream("/base3D.zir");
        final String Filename="base3D.zir";
        if (!JZirkelCanvas.getCurrentZC().isEmpty()) {
            tab_main_panel.newTabBtn();

        }
        doLoad(Filename, o, true);
        ZirkelFrame zf=JZirkelCanvas.getCurrentZF();
        if (zf!=null) {
            zf.Filename="";
        }
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                ZirkelCanvas zc=JZirkelCanvas.getCurrentZC();
                if (zc!=null) {
                    zc.JCM.fix3Dcomments();
                }
            }
        });
    }

    public static void saveFileAs() {
        if (Media.getMedias().size()>0) {
            JOptionPane.showMessageDialog(JZirkelCanvas.getCurrentZC(), Global.Loc("media.saveas"));
            saveWorkBookAs();
        } else {
            String filename=getSaveFile();
            if (filename!=null) {
                saveFile(filename, false, ".zir", false);
            }
        }
    }

    public static void saveFile() {
        if (JZirkelCanvas.isWorkBook()) {
            saveWorkBook(JZirkelCanvas.getWorkBookFileName());
        } else if (Media.getMedias().size()>0) {
            JOptionPane.showMessageDialog(JZirkelCanvas.getCurrentZC(), Global.Loc("media.saveas"));
            saveWorkBookAs();
        } else {
            if (JZirkelCanvas.getCurrentZC()==null) {
                return;
            }
            ZirkelFrame ZF=JZirkelCanvas.getCurrentZF();
            ZirkelCanvas ZC=JZirkelCanvas.getCurrentZC();
            String filename=(ZF.haveFile())?ZF.Filename:getSaveFile();
            if (filename!=null) {
                saveFile(filename, false, ".zir", !ZF.haveFile());
            }
        }
    }

    private static boolean ICanSave(final String Fname, final boolean ask) {
        if (!ask) {
            return true;
        }
        if (!new File(Fname).exists()) {
            return true;
        }
        return (JOptionPane.showConfirmDialog(null, Global.Loc("filedialog.savemessage1")+Fname+Global.Loc("filedialog.savemessage2"), "",
                JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION);
    }

    private static void doSave(ZirkelCanvas zc, String Filename, OutputStream o) {
        try {
            if (o==null) {
                o=new FileOutputStream(Filename);
                if (ZirkelFrame.isCompressed(Filename)) {
                    o=new GZIPOutputStream(o, 10000);
                }
            }
            zc.save(o, true, true, false, true, zc.getMacros(), "");
            o.close();
        } catch (Exception e) {
        }
    }

    private static void saveFile(String Filename, final boolean restrict, final String ext, final boolean ask) {
        if (JZirkelCanvas.getCurrentZC()==null) {
            return;
        }
        if (Filename==null) {
            return;
        }
        ZirkelFrame ZF=JZirkelCanvas.getCurrentZF();
        ZirkelCanvas ZC=JZirkelCanvas.getCurrentZC();
        if ((!Filename.endsWith(".zirz"))&&(!Filename.endsWith(".zir"))) {
            Filename+=ext;
        }
        if (ICanSave(Filename, ask)) {
//            SetMacrosProtectionForSaveProcess(macrostree.JML.MacroTreeTopNode);
            OutputStream o;
            try {
                ZF.ZC.getConstruction().BackgroundFile=ZF.Background;
                ZF.ZC.getConstruction().ResizeBackground=Global.getParameter(
                        "background.usesize", false);
                doSave(ZF.ZC, Filename, null);
                ZF.Filename=Filename;
                tab_main_panel.setCurrentTabName(FileName.filename(Filename), Filename);
            } catch (final Exception e) {
                final Warning w=new Warning(pipe_tools.getFrame(), Global.Loc("warning.save"),
                        FileName.chop(32, e.toString(), 64), Global.Loc("warning"), true);
                w.center(null);
                w.setVisible(true);
            }
//            ResetMacrosProtection(macrostree.JML.MacroTreeTopNode);
        }
        pipe_tools.TabHaveChanged(false);
    }

    /*********************************************
     * Workbooks part : open and save zirs files
     *********************************************/
    public static String getConstruction(ZirkelCanvas zc) {
        try {
            final ByteArrayOutputStream out=new ByteArrayOutputStream();
            doSave(zc, null, out);
            return out.toString("utf-8");
        } catch (Exception ex) {
            return "Error";
        }
    }

    public static String convertStreamToString(InputStream is) {
        if (is!=null) {
            StringBuilder sb=new StringBuilder();
            String line;
            try {
                BufferedReader reader=new BufferedReader(new InputStreamReader(is, "UTF-8"));
                while ((line=reader.readLine())!=null) {
                    sb.append(line).append("\n");
                }
                is.close();
            } catch (Exception e) {
                return null;
            }
            return sb.toString();
        } else {
            return null;
        }
    }

    public static void saveWorkBookAs() {
        final String filename=getSaveFile();
        if (filename!=null) {
            saveWorkBook(filename);
        }
    }

    public static void saveWorkBook(String filename) {
        if (filename==null) {
            return;
        }
        if (!filename.endsWith(".zirs")) {
            filename+=".zirs";
        }
        try {
            // Create the ZIP file

            ZipOutputStream out=new ZipOutputStream(new FileOutputStream(filename));

            // Save the workbook :

            Progress_Bar.create(Global.Loc("progressbar.workbooksavemessage"), 0, tab_main_panel.getBTNSsize()-1);

            for (int i=0; i<tab_main_panel.getBTNSsize(); i++) {
                tab_btn btn=tab_main_panel.getBTN(i);
                ZirkelCanvas ZC=btn.getPanel().getZC();
                out.putNextEntry(new ZipEntry(btn.getTabName()+".zir"));


                if (btn.getPanel().getByteArrayInputFile()==null) {
                    ByteArrayOutputStream file=new ByteArrayOutputStream();
                    doSave(ZC, null, file);
                    out.write(file.toByteArray());
                } else {
                    out.write(btn.getPanel().getByteArrayInputFile());
                }
                out.flush();
                out.closeEntry();
                Progress_Bar.nextValue();
            }
            for (int i=0; i<Media.getMedias().size(); i++) {
                out.putNextEntry(new ZipEntry(Media.getMedias().get(i).getImageFileName()));
                out.write(Media.getMedias().get(i).getImageBytes());
            }
            out.putNextEntry(new ZipEntry("preferences.txt"));
            out.write(createPreferencesFile());

            Progress_Bar.close();

            out.close();
        } catch (IOException e) {
        }

        // set workbook mode :
        JZirkelCanvas.setWorkBookFileName(filename, true);
    }

    public static byte[] createPreferencesFile() {
        String file="** COMMON PART (APPLET and Application) :\n";
        file+="\n";
        file+="showcomments="+Global.getParameter("comment", true)+"\n";
        file+="showpalette="+RightPanel.isPanelVisible()+"\n";
        file+="showleftpanel="+LeftPanel.isPanelVisible()+"\n";
        file+="showtabs="+(tab_main_panel.getBTNSsize()>1)+"\n";
        file+="showstatus="+(tab_main_panel.getBTNSsize()>1)+"\n";
        file+="currenttab="+(tab_main_panel.getActiveBtnPos()+1);
        file+="\n\n\n";
        file+="** APPLICATION SPECIFIC PART :\n";
        file+="\n";
        file+="window_width="+pipe_tools.getWindowSize().width+"\n";
        file+="window_height="+pipe_tools.getWindowSize().height+"\n";
        file+="\n";
        return file.getBytes();
    }

    public static void openWorkBook() {
        final String filename=getOpenFile();
        if (filename!=null) {
            openWorkBook(filename);
        }
    }

    // OpenWork book from Application :
    public static void openWorkBook(String filename) {
        try {
            ZipFile zpf=new ZipFile(filename);
            String prefsFileContent=null;

            Progress_Bar.create(Global.Loc("progressbar.workbookloadmessage"), 0, Collections.list(zpf.entries()).size());
            Enumeration entries=zpf.entries();

            // remember last tab button :
            tab_btn lastbtn=tab_main_panel.getLastBtn();
            // remember last tab position before adding new ones :
            int last_tab_pos=tab_main_panel.getBTNSsize()-1;


            while (entries.hasMoreElements()) {
                ZipEntry entry=(ZipEntry) entries.nextElement();
                if (validZirkelFileName(entry.getName())) {
                    tab_btn curbtn=tab_main_panel.addBtn(entry.getName());
                    curbtn.getPanel().setInputFile(zpf.getInputStream(entry));
                } else if (validImageFileName(entry.getName())) {
                    Media.createMedia(entry.getName(), copyToByteArray(zpf.getInputStream(entry)));
                } else if (validPreferencesFileName(entry.getName())) {
                    prefsFileContent=convertStreamToString(zpf.getInputStream(entry));
                }
                Progress_Bar.nextValue();
            }

            // set workbook mode :
            JZirkelCanvas.setWorkBookFileName(filename, false);
            Progress_Bar.close();

//            if (firstbtn!=null) {
//                tab_main_panel.setActiveBtn(firstbtn);
//                tab_main_panel.showActiveBtn();
//            }

            if (prefsFileContent!=null) {
                applyWorkBookPreferences(prefsFileContent, last_tab_pos);
            } else {
                tab_main_panel.setActiveBtn(1);
                tab_main_panel.showActiveBtn();
            }

            // if last tab canvas is empty, then remove it :
            if ((lastbtn.getPanel().getZC().isEmpty())&&(lastbtn.getPanel().getByteArrayInputFile()==null)) {
                tab_main_panel.removeBtn(lastbtn);
            }

            // I know, this is weird, but it work's (for palette display) :
            pipe_tools.setWindowComponents();
            pipe_tools.setWindowComponents();
            Open_left_panel_btn.setmode();
            Open_middle_panel_btn.setmode();
            Open_right_panel_btn.setmode();
            JGeneralMenuBar.initToggleItems();
            tab_main_panel.initToggleItems();


        } catch (Exception e) {
            return;
        }
    }

    /**
     * inside the workbook zirs archive, "preferences.txt" contains properties with
     * following structure : <property>=<value>
     * @param prefs : content of the "preferences.txt" file
     * @param property : the property we want to read
     * @return the value of the property
     */
    public static String getPref(String prefs, String property) {
        Matcher m=Pattern.compile("\\Q"+property+"=\\E(\\w+)\\W", Pattern.MULTILINE).matcher(prefs);
        if (m.find()) {
            return m.group(1);
        }
        return null;
    }

    /**
     * Read and apply workbook preferences : "preferences.txt" inside the "zirs" archive
     * @param prefs : content of the "preferences.txt" file
     * @param last_tab_pos : last tab position before adding the zirs
     */
    public static void applyWorkBookPreferences(final String prefs, int last_tab_pos) {

        int tabnum=last_tab_pos;
        try {
            tabnum+=Integer.parseInt(getPref(prefs, "currenttab"));
        } catch (Exception e) {
            tabnum=last_tab_pos;
        }

        tab_main_panel.setActiveBtn(tabnum);
        tab_main_panel.showActiveBtn();

        Global.setParameter("comment", "true".equals(getPref(prefs, "showcomments")));
        RightPanel.showPanel("true".equals(getPref(prefs, "showpalette")));
        LeftPanel.showPanel("true".equals(getPref(prefs, "showleftpanel")));
        if (pipe_tools.isApplet()) {
            themes.setShowTabs("true".equals(getPref(prefs, "showtabs")));
            themes.setShowStatus("true".equals(getPref(prefs, "showstatus")));
        } else {
            themes.setShowTabs(true);
            themes.setShowStatus(true);
        }
        try {
            int w=Integer.parseInt(getPref(prefs, "window_width"));
            int h=Integer.parseInt(getPref(prefs, "window_height"));
            pipe_tools.setAndCheckWindowSize(w, h);
        } catch (Exception e) {
        }
    }

    // Open WorkBook from applet :
    public static void openWorkBook(URL url) {
        try {
            ZipInputStream zpf=new ZipInputStream(url.openStream());
            int length=0;
            for (ZipEntry entry=zpf.getNextEntry(); entry!=null; entry=zpf.getNextEntry()) {
                length++;
            }
            Progress_Bar.create(Global.Loc("progressbar.workbookloadmessage"), 0, length);
            zpf=new ZipInputStream(url.openStream());
            String prefsFileContent=null;
            // remember last tab button :
            final tab_btn lastbtn=tab_main_panel.getLastBtn();
            for (ZipEntry entry=zpf.getNextEntry(); entry!=null; entry=zpf.getNextEntry()) {
                if (validZirkelFileName(entry.getName())) {
                    tab_btn curbtn=tab_main_panel.addBtn(entry.getName());
                    ByteArrayOutputStream outBuffer=new ByteArrayOutputStream();
                    int read;
                    while ((read=zpf.read())!=-1) {
                        outBuffer.write(read);
                    }
                    curbtn.getPanel().setInputFile(outBuffer.toByteArray());
                } else if (validImageFileName(entry.getName())) {
                    ByteArrayOutputStream outBuffer=new ByteArrayOutputStream();
                    int read;
                    while ((read=zpf.read())!=-1) {
                        outBuffer.write(read);
                    }
                    Media.createMedia(entry.getName(), outBuffer.toByteArray());
                } else if (validPreferencesFileName(entry.getName())) {
                    ByteArrayOutputStream outBuffer=new ByteArrayOutputStream();
                    int read;
                    while ((read=zpf.read())!=-1) {
                        outBuffer.write(read);
                    }
                    prefsFileContent=new String(outBuffer.toByteArray());
                }
            }

            Progress_Bar.close();
            JZirkelCanvas.setWorkBookFileName(url.getFile(), false);


            if (prefsFileContent!=null) {
                applyWorkBookPreferences(prefsFileContent, 0);
            } else {
                tab_main_panel.setActiveBtn(0);
                tab_main_panel.showActiveBtn();
            }

            // if last tab canvas is empty, then remove it :
            if ((lastbtn.getPanel().getZC().isEmpty())&&(lastbtn.getPanel().getByteArrayInputFile()==null)) {
                tab_main_panel.removeBtn(lastbtn);
            }

            // I know, this is weird, but it work's (for palette display) :
            pipe_tools.setWindowComponents();
            pipe_tools.setWindowComponents();
            Open_left_panel_btn.setmode();
            Open_middle_panel_btn.setmode();
            Open_right_panel_btn.setmode();
            JGeneralMenuBar.initToggleItems();
            tab_main_panel.initToggleItems();


        } catch (Exception e) {
            System.out.println("Workbook reading error");
            return;
        }
    }

    public static byte[] copyToByteArray(InputStream in) {
        int BUFFER_SIZE=4096;
        ByteArrayOutputStream out=new ByteArrayOutputStream(BUFFER_SIZE);
        try {
            int byteCount=0;
            byte[] buffer=new byte[BUFFER_SIZE];
            int bytesRead=-1;
            while ((bytesRead=in.read(buffer))!=-1) {
                out.write(buffer, 0, bytesRead);
                byteCount+=bytesRead;
            }
            out.flush();
            in.close();
            out.close();
        } catch (IOException e) {
        }
        return out.toByteArray();
    }

    public static void open(String filename) {
        if ((filename.endsWith(".mcr"))) {
            openMacro(filename);
        } else if ((filename.endsWith(".zirs"))) {
            openWorkBook(filename);
        } else {
            openFile(filename, null, false);
        }
    }

    public static void OpenStartupFiles() {
        for (int i=0; i<StartupFiles.size(); i++) {
            final String filename=(String) StartupFiles.get(i);
            open(filename);
        }
        StartupFiles.clear();
    }

    public static void FirstRun() {
        if (isStartup) {
            JPropertiesBar.CreatePopertiesBar();
            MainWindow mw=new MainWindow();
            PaletteManager.init();
            PaletteManager.setSelected_with_clic("point", true);
            JLogoWindow.DisposeLogoWindow();
            JZirkelCanvas.ActualiseMacroPanel();
        }
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                OpenStartupFiles();
            }
        });

        isStartup=false;
    }

    /******************************************************
     ****************** EXPORT PART ***********************
     ******************************************************/
    public static void savepng(final boolean issave) {
        ZirkelFrame ZF=JZirkelCanvas.getCurrentZF();
        if (ZF==null) {
            return;
        }
        if (issave) {
            final rene.dialogs.ExportPictureDlg dlg=new rene.dialogs.ExportPictureDlg(
                    pipe_tools.getFrame());
            dlg.setPictureWidth(ZF.ZC.getSize().width);
            dlg.setPictureHeight(ZF.ZC.getSize().height);
            dlg.setPercentScale(100);
            if (dlg.select()) {
                ZF.ZC.startWaiting();
                final double Scale=((double) dlg.getPercentScale())/100.0;
                final int w=(int) (((double) ZF.ZC.getSize().width)*Scale);
                final int h=(int) (((double) ZF.ZC.getSize().height)*Scale);
                ZF.ZC.PointSize=(int) (((double) Global.getParameter(
                        "minpointsize", 3))*Scale);
                ZF.ZC.FontSize=(int) (((double) Global.getParameter(
                        "minfontsize", 12))*Scale);
                ZF.ZC.IW=w;
                ZF.ZC.IH=h;
                final Image I=ZF.ZC.createImage(w, h);
                final rene.zirkel.graphics.MyGraphics13 IG=new rene.zirkel.graphics.MyGraphics13(
                        I.getGraphics(), Scale, ZF.ZC, null);
                IG.setSize(w, h);
                IG.setDefaultFont((int) ZF.ZC.FontSize, Global.getParameter(
                        "font.large", false), Global.getParameter("font.bold",
                        false));
                ZF.ZC.recompute();
                IG.clearRect(0, 0, w, h, Color.white);
                ZF.ZC.dopaint(IG);
                ZF.ZC.endWaiting();

                final int dpi=300;
                try {

                    final BufferedOutputStream out=new BufferedOutputStream(
                            new FileOutputStream(dlg.getFileName()));
                    final PngEncoder png=new PngEncoder(I,
                            PngEncoder.NO_ALPHA, 0, 9);
                    png.setDPI(dpi);
                    out.write(png.pngEncode());
                    out.close();
                } catch (final Exception e) {
                    // warning(e.toString());
                }
                // }
            }
        } else {
            ZF.ZC.startWaiting();
            int Scale=3;
            final int w=ZF.ZC.getSize().width*Scale;
            final int h=ZF.ZC.getSize().height*Scale;
            ZF.ZC.PointSize=Global.getParameter("minpointsize", 3)*Scale;
            ZF.ZC.FontSize=Global.getParameter("minfontsize", 12)*Scale;
            ZF.ZC.IW=w;
            ZF.ZC.IH=h;
            Image I=ZF.ZC.createImage(w, h);
            final rene.zirkel.graphics.MyGraphics13 IG=new rene.zirkel.graphics.MyGraphics13(
                    I.getGraphics(), Scale, ZF.ZC, null);
            IG.setSize(w, h);
            IG.setDefaultFont((int) ZF.ZC.FontSize, Global.getParameter(
                    "font.large", false), Global.getParameter("font.bold",
                    false));
            ZF.ZC.recompute();
            IG.clearRect(0, 0, w, h, Color.white);
            ZF.ZC.dopaint(IG);
            ZF.ZC.endWaiting();

            try {
                final Clipboard clipboard=pipe_tools.getFrame().getToolkit().getSystemClipboard();
                final ImageSelection is=new ImageSelection(I);
                clipboard.setContents(is, null);
            } catch (final Exception e) {
                Scale=1;
                I=null;
//                repaint();
                JOptionPane.showMessageDialog(null,
                        "Sorry : error occured while copying...");
            }

        }

    }

    public static void saveeps() {
        ZirkelFrame ZF=JZirkelCanvas.getCurrentZF();
        if (ZF==null) {
            return;
        }
        final int Scale=1;
        final int w=ZF.ZC.getSize().width*Scale;
        final int h=ZF.ZC.getSize().height*Scale;
        ZF.ZC.PointSize=Global.getParameter("minpointsize", 3)*Scale;
        ZF.ZC.FontSize=Global.getParameter("minfontsize", 12)*Scale;

        ZF.ZC.IW=w;
        ZF.ZC.IH=h;
        ZF.ZC.recompute();
        final FileSystemView vueSysteme=FileSystemView.getFileSystemView();
        final File def=vueSysteme.getHomeDirectory();
        final File desk=vueSysteme.getChild(def, "Desktop");
        final File choice=(desk==null)?def:desk;
        final JFileChooser jfc=new javax.swing.JFileChooser(choice);
        jfc.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
        jfc.setApproveButtonText("Export to EPS");
        jfc.setAcceptAllFileFilterUsed(false);
        jfc.addChoosableFileFilter(new ImageFilter());

        final int rep=jfc.showSaveDialog(null);
        if (rep==JFileChooser.APPROVE_OPTION) {
            final File outputfile=jfc.getSelectedFile();
            final String filename=outputfile.getAbsolutePath();
            final String ext=(outputfile.getAbsolutePath().endsWith(".eps"))?""
                    :".eps";
            OutputStream o=null;
            try {
                o=new FileOutputStream(filename+ext);
            } catch (final FileNotFoundException ex) {
                ex.printStackTrace();
            }

            try {
                final MyGraphicsEPS eps=new MyGraphicsEPS(o, w, h);
                eps.setSize(w, h);
                eps.setLineWidth(Global.getParameter("minlinesize", 1));
                eps.setDefaultFont((int) ZF.ZC.FontSize, Global.getParameter(
                        "font.large", false), Global.getParameter("font.bold",
                        false));

                ZF.ZC.dopaint(eps);
                eps.close();
                o.close();
            } catch (final IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void saveSVG() {
        ZirkelFrame ZF=JZirkelCanvas.getCurrentZF();
        if (ZF==null) {
            return;
        }
        final int Scale=1;
        final int w=ZF.ZC.getSize().width*Scale;
        final int h=ZF.ZC.getSize().height*Scale;
        ZF.ZC.PointSize=Global.getParameter("minpointsize", 3)*Scale;
        ZF.ZC.FontSize=Global.getParameter("minfontsize", 12)*Scale;

        ZF.ZC.IW=w;
        ZF.ZC.IH=h;
        ZF.ZC.recompute();

        final FileSystemView vueSysteme=FileSystemView.getFileSystemView();
        final File def=vueSysteme.getHomeDirectory();
        final File desk=vueSysteme.getChild(def, "Desktop");
        final File choice=(desk==null)?def:desk;
        final JFileChooser jfc=new javax.swing.JFileChooser(choice);
        jfc.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
        jfc.setApproveButtonText("Export to SVG");
        jfc.setAcceptAllFileFilterUsed(false);
        jfc.addChoosableFileFilter(new ImageFilter());

        final int rep=jfc.showSaveDialog(null);

        if (rep==JFileChooser.APPROVE_OPTION) {
            final File outputfile=jfc.getSelectedFile();
            final String filename=outputfile.getAbsolutePath();
            final String ext=(outputfile.getAbsolutePath().endsWith(".svg"))?""
                    :".svg";
            try {
                OutputStream o=new FileOutputStream(filename+ext);
                if (ZirkelFrame.isCompressed(filename)) {
                    o=new GZIPOutputStream(o);
                }
                final PrintWriter out=new PrintWriter(new OutputStreamWriter(
                        o, "UTF8"));
                final MyGraphicsSvg svg=new MyGraphicsSvg(out, w, h);
                svg.setSize(w, h);
                svg.setDefaultFont((int) ZF.ZC.FontSize, Global.getParameter(
                        "font.large", false), Global.getParameter("font.bold",
                        false));
                ZF.ZC.dopaint(svg);
                svg.close();
                out.close();
            } catch (final Exception e) {
            }
        }
    }
}
