import com.sun.java.swing.*;
import com.sun.java.swing.tree.*;
import com.sun.java.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.*;
import java.util.*;

public class WebTreePanel extends JPanel implements TreeExpansionListener {

  DefaultTreeModel treeModel;
  JTree tree;

  DefaultMutableTreeNode racine;
  DefaultMutableTreeNode hostname;
  DefaultMutableTreeNode currentnode;
  Explorer explorer;

  void buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) {
    /* parametrage du grid bag layout */
    gbc.gridx      = gx;
    gbc.gridy      = gy;
    gbc.gridwidth  = gw;
    gbc.gridheight = gh;
    gbc.weightx    = wx;
    gbc.weighty    = wy;
  }
  
  public WebTreePanel( Explorer e ) {
    /* constructeur */
    DefaultMutableTreeNode LogicWebTree;
    GridBagLayout gridBagtp          = new GridBagLayout();
    GridBagConstraints constraintstp = new GridBagConstraints();
    racine    = new DefaultMutableTreeNode("WebSite                 ");
    treeModel = new DefaultTreeModel(racine);
    tree      = new JTree(treeModel);
    explorer  = e;
    racine.add(new DefaultMutableTreeNode());
    tree.addTreeExpansionListener(this);

    setLayout(gridBagtp);
    constraintstp.fill = GridBagConstraints.BOTH;
    buildConstraints(constraintstp,0,0,1,1,100,100);
    gridBagtp.setConstraints (tree , constraintstp);
    add(tree);
    setAutoscrolls(true);
    setMinimumSize(new Dimension(20,20)); 
    setVisible(true);
    //tree.setRootVisible(false); /* pour cacher la racine */
  }

  public synchronized void AddHost(String host) {
    /* effacer le map du site precedent */
    racine.removeAllChildren();
    /* ajouter le nouveau site */
    hostname = new DefaultMutableTreeNode(host);
    /* ajoute une feuille pour avoir l'apparence d'un noeud */
    hostname.add(new DefaultMutableTreeNode()); 
    racine.add(hostname);
    /* rafraichissement */
    treeModel.nodeStructureChanged(racine);
    treeModel.nodeStructureChanged(hostname);
  }
  
  public synchronized void AddDirectory(Info info) {
    /* dir est de la forme /dir1/dir2/dir3/.../dirn/file */
    String fullpath;
    int    idx;

    String DirectoryString;
    StringTokenizer path;
    int i;
    int j = 0;
    DefaultMutableTreeNode NewDirectoryNode;
    DefaultMutableTreeNode DirectoryNode = hostname;
    boolean DirectoryExists;

    /* extraction du path */
    fullpath = info.getName();
    idx      = fullpath.lastIndexOf("/");
    if(idx != -1 && info.getType()!=Info.DIR) {
      fullpath=fullpath.substring(0, idx);
    }

    path = new StringTokenizer(fullpath,"/");
    while (path.hasMoreTokens()) {
      DirectoryExists = false;
      DirectoryString = path.nextToken();
      
      if (DirectoryNode.getFirstChild().toString()!=null) {
	for (i=0;i<DirectoryNode.getChildCount();i++) {
	  if (DirectoryString.compareTo(DirectoryNode.getChildAt(i).toString())==0) {
	    DirectoryExists = true;
	    j=i;
	  }
	}
      }
       else {
	DirectoryNode.remove(0);
      }

      if (DirectoryExists==false) {
	/* le repertoire n'existe pas */
	NewDirectoryNode = new DefaultMutableTreeNode(DirectoryString);
	DirectoryNode.add(NewDirectoryNode);
	/* rafraichissement */
	treeModel.nodeStructureChanged(DirectoryNode);
	/* ajout du repertoire */
	NewDirectoryNode.add(new DefaultMutableTreeNode());
	/* on descence d'un niveau */
	DirectoryNode = NewDirectoryNode;

      }
      else {
	/* le repertoire existe, on descend dans celui-ci */
	DirectoryNode = (DefaultMutableTreeNode)DirectoryNode.getChildAt(j);
      }
    }
  }

  public synchronized void upToNode() {

    TreePath chemin;
    int      taille;

    /* recuperation du chemin */
    if (!tree.isSelectionEmpty()) {
      chemin = tree.getSelectionPath();
      taille = chemin.getPathCount()-1;
      if (taille > 1 ) {
	Object tabchemin[] = new Object[taille];
	for (int i =0; i<chemin.getPathCount()-1; i++) 
	  tabchemin[i] = chemin.getPathComponent(i);
	chemin = new TreePath(tabchemin);
	/* affectation du chemin */
	tree.setSelectionPath(chemin);
	tree.collapsePath(chemin);
      }
    }
  }

  public synchronized void downToNode(String path, String directory) {
      StringTokenizer pathtoken;
      String DirectoryString;
      int i;
      TreePath chemin;

      pathtoken = new StringTokenizer(path,"/");

      Object tabchemin[] = new Object[pathtoken.countTokens()+2+1];
      
      tabchemin[0] = racine.toString();
      tabchemin[1] = hostname.toString();
      i = 2;
      while (pathtoken.hasMoreTokens()) {
	  DirectoryString = pathtoken.nextToken();
	  tabchemin[i] = DirectoryString;
	  i++;

      }
      tabchemin[i] = directory;
      chemin = new TreePath(tabchemin);

      tree.setSelectionPath(chemin);
      //tree.collapsePath(chemin);
      tree.expandPath(chemin);
      //tree.treeDidChange();
  }

  public synchronized void treeCollapsed(TreeExpansionEvent e) {
    /* repliement de l'arbre */
    TreePath chemin = e.getPath();
    String   webpath = "";
    DefaultMutableTreeNode noeudtmp;
    DefaultMutableTreeNode noeud = (DefaultMutableTreeNode)chemin.getLastPathComponent();
    currentnode = noeud;
    if (noeud.getFirstChild().toString()==null)
      tree.collapsePath(e.getPath());
    for (int i =2; i< chemin.getPathCount(); i++) {
      /* on enleve la racine et le nom du host */
      noeudtmp = (DefaultMutableTreeNode)chemin.getPathComponent(i);
      webpath = webpath.concat(noeudtmp.toString());
      webpath = webpath.concat("/");
    } 
    if ( chemin.getPathCount() > 1 )
      explorer.loadBrowser(webpath);
  }

  public synchronized void treeExpanded(TreeExpansionEvent e) {

    /* evenement : l'arbre est deplie */
    TreePath chemin = e.getPath();
    String   webpath = "";
    DefaultMutableTreeNode noeudtmp;
    DefaultMutableTreeNode noeud = (DefaultMutableTreeNode)chemin.getLastPathComponent();
    currentnode = noeud;
    if (noeud.getFirstChild().toString()==null)
      tree.collapsePath(e.getPath());
    for (int i =2; i< chemin.getPathCount(); i++) {
      /* on enleve la racine et le nom du host */
      noeudtmp = (DefaultMutableTreeNode)chemin.getPathComponent(i);
      webpath = webpath.concat(noeudtmp.toString());
      webpath = webpath.concat("/");
    } 
    if ( chemin.getPathCount() > 1 )
      explorer.loadBrowser(webpath);
  }
}

