/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *   2005 C.Marchand - christophe.marchand@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * XEMELIOS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package fr.gouv.finances.cp.xemelios.plugins;

import java.awt.Graphics;
import java.util.Hashtable;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import org.apache.log4j.Logger;
import org.jdesktop.swingworker.SwingWorker;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import fr.gouv.finances.cp.utils.Pair;
import fr.gouv.finances.cp.utils.ui.IhmFactory;
import fr.gouv.finances.cp.xemelios.common.config.DocumentModel;
import fr.gouv.finances.cp.xemelios.common.config.ElementModel;
import fr.gouv.finances.cp.xemelios.common.config.EtatModel;
import fr.gouv.finances.cp.xemelios.common.config.PluginModel;
import fr.gouv.finances.cp.xemelios.importers.ImportServiceSwingProvider.PaintableProgress;
import fr.gouv.finances.cp.xemelios.ui.MainWindow;
import fr.gouv.finances.cp.xemelios.ui.SearchWindow;

/**
 * Defines contract to make plugins.
 * An implementation must provide a constructor with no parameters
 * @author chm
 */
public abstract class XemeliosPlugin extends SwingWorker<Object,String> {
    private static final Logger logger = Logger.getLogger(XemeliosPlugin.class);
    public static final int TYPE_SEARCH = 1;
    public static final int TYPE_EXPORT = 2;
    
    private ElementModel elementModel;
    private EtatModel etatModel;
    private DocumentModel documentModel;
    
    private Hashtable<String,String> params;
    private PluginModel pm;
    private int maxProgress;
    private String progressMessage;
    private ProgressDlg progress = null;
    private long start;
    private SearchWindow sw;
    private Pair collectivite=null, budget=null;
    
    public abstract int getPluginType();
    private MainWindow owner;

    public void setOwner(fr.gouv.finances.cp.xemelios.ui.MainWindow owner) { this.owner = owner; }
    public JFrame getOwner() { return owner; }
    public void setElementModel(ElementModel em) { 
        this.elementModel=em;
        this.etatModel=this.elementModel.getParent();
        this.documentModel=this.etatModel.getParent();
    }
    protected final ElementModel getElementModel() { return elementModel; }
    protected final EtatModel getEtatModel() { return etatModel; }
    protected final DocumentModel getDocumentModel() { return documentModel; }
    public void setParameters(Hashtable<String,String> params) { this.params=params; }
    protected final Hashtable<String,String> getParameters() { return params; }
    public void setModel(PluginModel pm) { this.pm=pm; }
    public void setStart(long start) { this.start=start; }
    public long getStart() { return start; }
    protected final PluginModel getPluginModel() { return pm; }
    public void setCollectivite(Pair collectivite) { this.collectivite=collectivite; }
    public void setBudget(Pair budget) { this.budget=budget; }
    public Pair getBudget() { return budget; }
    public Pair getCollectivite() { return collectivite; }
    protected void setProgressInfos(int maxProgress, String progressMessage) {
        this.maxProgress = maxProgress;
        this.progressMessage = progressMessage;
    }
    protected void pushProgress() {
        if(progress!=null) {
            progress.pushProgress();
        }
    }
    protected void setProgressVisible(boolean show) {
        if(show) {
            progress = new ProgressDlg(owner,maxProgress, progressMessage);
            progress.setVisible(true);
        } else if(progress!=null) {
            progress.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            progress.setVisible(false);
        }
    }
    @Override
	public void done() {
        owner.stopWaiter();
    }
    public void setSearchWindow(SearchWindow sw) { this.sw=sw; }
    public SearchWindow getSearchWindow() { return sw; }

	public final class ProgressDlg extends JDialog {
        /**
         * Comment for <code>serialVersionUID</code>
         */
        private static final long serialVersionUID = 1L;
        public static final String DEFAULT_TEXT = "Recherche en cours : ";
        
        private PaintableProgress globalProgress;
        private int maxProgress,value=0;
        private String progressMessage;

        public ProgressDlg(JFrame owner, int maxProgress, String progressMessage) {
            super(owner,DEFAULT_TEXT);
            this.maxProgress=maxProgress;
            this.progressMessage=progressMessage;
            initComponents();
        }
        protected void initComponents() {
            IhmFactory iF = IhmFactory.newInstance();
    		FormLayout fl = null;
   		    fl = new FormLayout("3dlu,pref,3dlu","3dlu,pref,1dlu,pref,3dlu");
    		CellConstraints cc = new CellConstraints();
    		PanelBuilder pb = new PanelBuilder(fl);

            pb.add(iF.newLabel(progressMessage,"normal"),	cc.xy(2,2));
            globalProgress = new PaintableProgress(0,100);
            globalProgress.setStringPainted(true);
            globalProgress.setMaximum(maxProgress);
            pb.add(globalProgress,							cc.xy(2,4));

            setContentPane(pb.getPanel());
            setResizable(false);
            setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
            pack();
            setLocationRelativeTo(getOwner());
            setVisible(true);
            Graphics g = getGraphics();
            g.setClip(0,0,getWidth(),getHeight());
            paint(g);
        }
    	public void repaintImmediatly() {
    	    Runnable code = new Runnable() {
    	        public void run() {
    	    	    globalProgress.paintImmediatly();
    	            Graphics g = getGraphics();
    	            g.setClip(0,0,getWidth(),getHeight());
    	    	    if(isLightweight()) {
    	    	        paint(g);
    	    	    } else {
    	    	        update(g);
    	    	    }
    	        }
    	    };
    	    if(SwingUtilities.isEventDispatchThread()) {
    	        code.run();
    	    }
    	    else {
	    	    try { SwingUtilities.invokeAndWait(code); } catch(Throwable t) {
	    	        logger.error("repaintImmediatly",t);
	    	    }
    	    }
    	}
    	public void pushProgress() {
    	    value++;
//    	    logger.debug("progress: "+value);
    	    globalProgress.setValue(value);
    	    repaintImmediatly();
    	    //repaint();
    	}
    }
}
