package com.dbxml.db.admin.xmleditor;

/*
 * dbXML - Native XML Database
 * Copyright (C) 1999-2004  The dbXML Group, L.L.C.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Id: ElementResourceMap.java,v 1.2 2004/02/12 00:17:55 bradford Exp $
 */

import com.dbxml.util.Configuration;
import java.awt.Color;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * ElementResourceMap
 */

public final class ElementResourceMap {
   private static final String RESOURCE = "resource";
   private static final String CLASS = "class";
   private static final String NAME = "name";
   private static final String ICON = "icon";
   private static final String FGCOLOR = "fgcolor";
   private static final String BGCOLOR = "bgcolor";
   private static final String EDITOR = "editor";

   private Map map = new HashMap();

   public ElementResourceMap() {
   }

   public ElementResourceMap(Document doc) {
      this(doc.getDocumentElement());
   }

   public ElementResourceMap(Element elem) {
      setConfig(elem);
   }

   public void setConfig(Configuration config) {
      try {
         setConfig(config.getElement());
      }
      catch ( Exception e ) {
         e.printStackTrace(System.err);
      }
   }

   public void setConfig(Element elem) {
      NodeList nl = elem.getChildNodes();
      for ( int i = 0; i < nl.getLength(); i++ ) {
         Node n = nl.item(i);
         if ( n.getNodeType() == Node.ELEMENT_NODE ) {
            Element e = (Element)n;
            if ( e.getTagName().equals(RESOURCE) ) {
               String name = e.getAttribute(NAME);
               String c = e.getAttribute(CLASS);
               String icon = e.getAttribute(ICON);
               String fg = e.getAttribute(FGCOLOR);
               String bg = e.getAttribute(BGCOLOR);
               String editor = e.getAttribute(EDITOR);
               map.put(name, new ResourceInfo(readColor(fg), readColor(bg), readIcon(c, icon), readEditor(editor)));
            }
         }
      }
   }

   private Icon readIcon(String cname, String name) {
      Icon ico = null;
      if ( cname != null && cname.length() > 0 ) {
         try {
            Class c = Class.forName(cname);
            ico = new ImageIcon(c.getResource(name));
         }
         catch ( Exception e ) {
            e.printStackTrace(System.err);
         }
      }
      else
         ico = new ImageIcon(name);
      return ico;
   }

   private Color readColor(String name) {
      Color color = null;
      try {
         if ( name.equals("black") )
            color = Color.black;
         else if ( name.equals("blue") )
            color = Color.blue;
         else if ( name.equals("cyan") )
            color = Color.cyan;
         else if ( name.equals("darkGray") )
            color = Color.darkGray;
         else if ( name.equals("gray") )
            color = Color.gray;
         else if ( name.equals("green") )
            color = Color.green;
         else if ( name.equals("lightGray") )
            color = Color.lightGray;
         else if ( name.equals("magenta") )
            color = Color.magenta;
         else if ( name.equals("orange") )
            color = Color.orange;
         else if ( name.equals("pink") )
            color = Color.pink;
         else if ( name.equals("red") )
            color = Color.red;
         else if ( name.equals("white") )
            color = Color.white;
         else if ( name.equals("yellow") )
            color = Color.yellow;
         else if ( name.startsWith("#") && name.length() == 7 ) {
            int ri = Integer.parseInt(name.substring(1, 2), 16);
            int gi = Integer.parseInt(name.substring(3, 4), 16);
            int bi = Integer.parseInt(name.substring(5, 6), 16);
            color = new Color(ri, gi, bi);
         }
         else {
            int c = Integer.parseInt(name);
            color = new Color(c);
         }
      }
      catch ( Exception e ) {
         e.printStackTrace(System.err);
      }
      return color;
   }

   private Class readEditor(String editor) {
      try {
         return Class.forName(editor);
      }
      catch ( Exception e ) {
         return null;
      }
   }

   private ResourceInfo getResourceInfo(String element) {
      return (ResourceInfo)map.get(element);
   }

   public Color getBackgroundColor(String element) {
      ResourceInfo r = getResourceInfo(element);
      return r != null ? r.bg : null;
   }

   public void setBackgroundColor(String element, Color color) {
      ResourceInfo r = getResourceInfo(element);
      if ( r == null ) {
         r = new ResourceInfo(null, color);
         map.put(element, r);
      }
      else
         r.bg = color;
   }

   public void removeBackgroundColor(String element) {
      ResourceInfo r = getResourceInfo(element);
      if ( r != null ) {
         r.bg = null;
         if ( r.fg == null && r.icon == null && r.editor == null )
            map.remove(element);
      }
   }

   public Color getForegroundColor(String element) {
      ResourceInfo r = getResourceInfo(element);
      return r != null ? r.fg : null;
   }

   public void setForegroundColor(String element, Color color) {
      ResourceInfo r = getResourceInfo(element);
      if ( r == null ) {
         r = new ResourceInfo(color);
         map.put(element, r);
      }
      else
         r.fg = color;
   }

   public void removeForegroundColor(String element) {
      ResourceInfo r = getResourceInfo(element);
      if ( r != null ) {
         r.fg = null;
         if ( r.bg == null && r.icon == null && r.editor == null )
            map.remove(element);
      }
   }

   public Icon getIcon(String element) {
      ResourceInfo r = getResourceInfo(element);
      return r != null ? r.icon : null;
   }

   public void setIcon(String element, Icon icon) {
      ResourceInfo r = getResourceInfo(element);
      if ( r == null ) {
         r = new ResourceInfo(icon);
         map.put(element, r);
      }
      else
         r.icon = icon;
   }

   public void removeIcon(String element) {
      ResourceInfo r = getResourceInfo(element);
      if ( r != null ) {
         r.icon = null;
         if ( r.fg == null && r.bg == null && r.editor == null )
            map.remove(element);
      }
   }

   public Class getEditor(String element) {
      ResourceInfo r = getResourceInfo(element);
      return r != null ? r.editor : null;
   }

   public void setEditor(String element, Class editor) {
      ResourceInfo r = getResourceInfo(element);
      if ( r == null ) {
         r = new ResourceInfo(editor);
         map.put(element, r);
      }
      else
         r.editor = editor;
   }

   public void removeEditor(String element) {
      ResourceInfo r = getResourceInfo(element);
      if ( r != null ) {
         r.editor = null;
         if ( r.fg == null && r.bg == null && r.icon == null )
            map.remove(element);
      }
   }

   public void clear() {
      map.clear();
   }


   /**
    * ResourceInfo
    */

   private class ResourceInfo {
      public Color fg;
      public Color bg;
      public Icon icon;
      public Class editor;

      public ResourceInfo(Color fg, Color bg, Icon icon, Class editor) {
         this.fg = fg;
         this.bg = bg;
         this.icon = icon;
         this.editor = editor;
      }

      public ResourceInfo(Color fg, Color bg, Icon icon) {
         this(fg, bg, icon, null);
      }

      public ResourceInfo(Class editor) {
         this.editor = editor;
      }

      public ResourceInfo(Color fg, Color bg) {
         this(fg, bg, null);
      }

      public ResourceInfo(Color fg) {
         this(fg, null);
      }

      public ResourceInfo(Icon icon) {
         this.icon = icon;
      }
   }
}
