package click.gui;
/*
 * RouterTreeModel.java -- a JTree model for element handlers
 * Douglas S. J. De Couto, Eddie Kohler
 *
 * Copyright (c) 2000 Massachusetts Institute of Technology.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * Further elaboration of this license, including a DISCLAIMER OF ANY
 * WARRANTY, EXPRESS OR IMPLIED, is provided in the LICENSE file, which is
 * also accessible at http://www.pdos.lcs.mit.edu/click/license.html
 */

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;

import click.runtime.ClickException;
import click.runtime.ClickInterface;
import click.runtime.HandlerInfo;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;

public class RouterTreeModel extends DefaultTreeModel {

  /**
   * 
   */
  private static final long serialVersionUID = -4700831629465359965L;
  Vector _dhl;

  static class HandlerUserObject {
    HandlerInfo _hinfo;
    String _name;

    HandlerUserObject(HandlerInfo hinfo, String name) {
      _hinfo = hinfo;
      _name = name;
    }

    HandlerUserObject(ClickInterface cs, String el, String name, String text) {
      _hinfo = new HandlerInfo(cs, el, name);
      _hinfo.canRead = true;
      _name = text;
    }

    public String toString() {
      return (_name == null ? _hinfo.toString() : _name);
    }
  }

  private static class HandlerComparator implements Comparator {
    public int compare(Object o1, Object o2) {
      HandlerInfo h1 = (HandlerInfo) o1;
      HandlerInfo h2 = (HandlerInfo) o2;
      return h1.handlerName.toLowerCase().compareTo(h2.handlerName.toLowerCase());
    }
  }

  public RouterTreeModel(List controllerList, int filter_type, String filter) {
    super(new DefaultMutableTreeNode("ClickController Root"));
    
    DefaultMutableTreeNode root = (DefaultMutableTreeNode) getRoot();
    _dhl = new Vector();

    for (int controller = 0; controller < controllerList.size(); controller++) {
      ClickInterface cs = (ClickInterface)controllerList.get(controller);

      DefaultMutableTreeNode csNode = new DefaultMutableTreeNode(cs.name());
      insertNodeInto(csNode, root, controller);
      
      try {
        MutableTreeNode node = new DefaultMutableTreeNode
                (new HandlerUserObject(cs, null, "config", "Configuration"));
        int nodePos = 0;
        insertNodeInto(node, csNode, nodePos++);
  
        node = new DefaultMutableTreeNode
                (new HandlerUserObject(cs, null, "flatconfig", "Flat Configuration"));
        insertNodeInto(node, csNode, nodePos++);
  
        Vector v = cs.getConfigElementNames();
        Collections.sort(v, String.CASE_INSENSITIVE_ORDER);
  
        Comparator handlerComparator = new HandlerComparator();
        for (int i = 0; i < v.size(); i++) {
          // The element might not actually exist!
          try {
            String elname = (String) v.elementAt(i);
  
            switch(filter_type) {
              case ClickController.MESHNODE:
                if (elname.indexOf("MeshNode") == -1) {
                  continue;
                }
                break;
  
              case ClickController.AP:
                if (elname.indexOf("access_point") == -1) {
                  continue;
                }
                break;
  
              case ClickController.BRN_IAPP:
                if (elname.indexOf("brn_iapp") == -1) {
                  continue;
                }
                break;
  
              case ClickController.DHT:
                if (elname.indexOf("dht") == -1) {
                  continue;
                }
                break;
  
              case ClickController.DSR:
                if (elname.indexOf("dsr") == -1) {
                  continue;
                }
                break;
  
              case ClickController.SERVICES:
                if (elname.indexOf("services") == -1) {
                  continue;
                }
                break;

              case ClickController.VLAN:
                if (elname.indexOf("vlan") == -1) {
                  continue;
                }
                break;
              case ClickController.CUSTOM:
                if (elname.indexOf(filter) == -1) {
                  continue;
                }
                break;

              case ClickController.ALL:
              default:
                // nothing todo
            }
  
            DefaultMutableTreeNode elnode = new DefaultMutableTreeNode(elname);
            Vector vh = cs.getElementHandlers(elname);
            Collections.sort(vh, handlerComparator);
            for (int j = 0; j < vh.size(); j++) {
              HandlerInfo hi = (HandlerInfo) vh.elementAt(j);
              DefaultMutableTreeNode hnode = new DefaultMutableTreeNode(hi);
              insertNodeInto(hnode, elnode, j);
            }
            insertNodeInto(elnode, csNode, nodePos++);
          } catch (ClickException e) {
          }
        }
  
        insertNodeInto(new DefaultMutableTreeNode
                (new HandlerUserObject(cs, null, "version", "Click version")),
                csNode, nodePos++);
  
        insertNodeInto(new DefaultMutableTreeNode
                (new HandlerUserObject(cs, null, "requirements", "Router requirements")),
                csNode, nodePos++);
  
        insertNodeInto(new DefaultMutableTreeNode
                (new HandlerUserObject(cs, null, "packages", "Installed packages")),
                csNode, nodePos++);
  
        insertNodeInto(new DefaultMutableTreeNode
                (new HandlerUserObject(cs, null, "classes", "Known element classes")),
                csNode, nodePos++);
  
      } catch (Throwable ex) {
        ex.printStackTrace();
        throw new RuntimeException(ex);
      }
    }
  }

  public interface DisplayHandlerListener {
    public void displayHandler(String h, String data);
  }

  public void installDisplayHandlerListener(DisplayHandlerListener l) {
    _dhl.addElement(l);
  }

}
