package com.uvigo.mhp.ui;

import com.uvigo.mhp.*;
import com.uvigo.mhp.xml.multiPanel.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.xml.bind.*;
import org.dvb.ui.*;
import org.havi.ui.*;
import com.uvigo.tMaestro.SCOCreator.tool.MainFrame;

// El fichero de configuraci�n para un objeto HMultiPanel contiene entradas
// con pares de cadenas, opcionalmente vacias, una por cada vista. Una cadena
// indica el nombre del contexto asociado, y otra el t�tulo para el HMultiPanel
// cuando se muestra la vista correspondiente (que se vea o no dicha cadena depende
// del look).

public class HMultiPanel extends HPanel implements ContextHandler {
     public static final int TIME_ALWAYS = 0;
    public static final int TIME_OK = 1;
    public static final int TIME_WRONG = 2;
    public static final int TIME_DELAYED = 4;
    public static final int TIME_LIMITED = 6;
    private CardLayout layout;
    private JAXBContext jc;
    private String configurationFile;
    private MultiPanelConfiguration conf;
    private java.util.List elements;
    private int delayedTimeMode;
    private int delayedTime;
    
    private int current;
    private ContextManager contextManager;
    private Vector listeners;
    private String context;
    private boolean cyclic;
    
    public HMultiPanel() {
        super();
        layout=new CardLayout(0,0);
        setLayout(layout);
        cyclic=false;
        configurationFile="";
        current=0;
        delayedTimeMode = TIME_ALWAYS;
        delayedTime=0;
        
        contextManager=null;
        listeners=new Vector();
        context="";
        
        try {
            jc=JAXBContext.newInstance("com.uvigo.mhp.xml.multiPanel");
            conf=null;
            elements=null;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public boolean isCyclic() {
        return cyclic;
    }
    
    public void setCyclic(boolean b) {
        boolean old=cyclic;
        if (old!=b) {
            cyclic=b;
            firePropertyChange("cyclic",new Boolean(old), new Boolean(b));
        }
    }
    public int getDelayedTimeMode() {
        return delayedTimeMode;
    }

    public void setDelayedTimeMode(int i) {

        int old = delayedTimeMode;
        if (i != old) {
            delayedTimeMode = i;
            repaint();
            firePropertyChange("delayedTimeMode", new Integer(old), new Integer(i));

        }
    }
    
    public int getDelayedTime() {
        return delayedTime;
    }

    public void setDelayedTime(int m) {
        int old = delayedTime;
        if (m != old) {
            delayedTime = m;
            firePropertyChange("delayedTime", new Integer(old), new Integer(m));
        }
    }
    public String getConfigurationFile() {
        return configurationFile;
    }
    
    public void setConfigurationFile(String s) {
        String old=configurationFile;
        // if (!(s.equals(old)))  { //Necesario eliminarlo, ya que puede cambiar el contenido del fichero y no su ruta
        
        try {
            if ((s==null) || (s=="")) return;
            
            //M: Direccionamiento relativo a "user.dir"
              String sBase= new String (MainFrame.oMainFrame.sDir+ "/");
            URL url=new URL("file:"+sBase+s);
            
            URLConnection con=url.openConnection();
            
            Unmarshaller u=jc.createUnmarshaller();
            u.setValidating(true);
            conf=(MultiPanelConfiguration) u.unmarshal(con.getInputStream());
            elements=conf.getElement();
            
            if ((elements!=null) && (elements.size()>0)) {
                ElementType et=(ElementType) elements.get(0);
                setLabel(et.getPanelTitle());
                gotoFirstContext();
            }
            
            configurationFile=s;
            firePropertyChange("configurationFile",old,s);
        } catch (Exception ex) {
            // El fichero de configuraci�n no se encuentra o no existe
            ex.printStackTrace();
        }
        //}
    }
    
    public String getContext() {
        return context;
    }
    
    public void setContext(String s) {
        if ((s==null) || (s.equals("")))
            return;
        
        if ((elements==null) || (elements.size()==0))
            return;
        
        for (int i=0;i<elements.size();i++) {
            if (i==getComponentCount())
                break;
            
            ElementType et=(ElementType) elements.get(i);
            if (et.getContextName().equals(s)) {
                switchTo(i);
                return;
            }
        }
        //System.out.println("Contexto desconocido");
    }
    
    public void gotoFirstContext() {
        if (getComponentCount()==0) return;
        switchTo(0);
    }
    
    public void gotoLastContext() {
        if (getComponentCount()==0) return;
        switchTo(getComponentCount()-1);
    }
    
    public void gotoNextContext() {
        if (getComponentCount()==0) return;
        
        if ((!cyclic) && (getComponent(getComponentCount()-1).isVisible()))
            return;
        
        switchTo((current+1)%getComponentCount());
    }
    
    public void gotoPreviousContext() {
        if (getComponentCount()==0) return;
        
        if ((!cyclic) && (getComponent(0).isVisible()))
            return;
        
        switchTo((current-1+getComponentCount())%getComponentCount());
    }
    
    public void addContextListener(ContextListener c) {
        if (!(listeners.contains(c)))
            listeners.add(c);
    }
    
    public void removeContextListener(ContextListener c) {
        if (listeners.contains(c))
            listeners.remove(c);
    }
    
    public ContextManager getContextManager() {
        return contextManager;
    }
    
    public void setContextManager(ContextManager c) {
        ContextManager old=contextManager;
        
        // si se indica el mismo ContextManager que estaba configurado, no se hace nada
        if (c==old)
            return;
        
        // si hab�a alguno configurado, nos damos de baja
        if (old!=null) {
            old.remove(this);
            removeContextListener(old);
        }
        
        // nos registramos en el nuevo ContextManager, pero s�lo si no es null
        if (c!=null) {
            addContextListener(c);
            c.add(this);
        }
        
        contextManager=c;
        firePropertyChange("contextManager",old,c);
    }
    
    private void switchTo(int i) {
        String old=context;
        if (current==i) return;
        
        try {
            ElementType et=(ElementType) elements.get(i);
            //System.out.println(et.getContextName()+" "+et.getPanelTitle());
            context=et.getContextName();
            setLabel(et.getPanelTitle());
        } catch (Exception ex) {
            // Si no hay tantos elementos definidos como vistas en el HMultiPanel
            // se utilizan cadenas vacias para el texto y el t�tulo
            context="";
            setLabel("");
        }
        
        current=i;
        setVisible(false);
        layout.first(this);
        for (int j=0;j<i;j++)
            layout.next(this);
        setVisible(true);
        if (!(context.equals(old)))
            fireEvent();
    }
    
    private void fireEvent() {
        for (int i=0;i<listeners.size();i++) {
            ContextListener c=(ContextListener) listeners.get(i);
            c.contextChanged(new ContextEvent(this, context));
        }
    }
    
    public String getSubcontext() {
        return null;
    }
}