/* StyleContext.java --
   Copyright (C) 2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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, or (at your option)
any later version.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.text;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Toolkit;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Hashtable;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;

public class StyleContext 
    implements Serializable, AbstractDocument.AttributeContext
{
  public class NamedStyle
    implements Serializable, Style
  {
    protected ChangeEvent changeEvent;
    protected EventListenerList listenerList;
      
    AttributeSet attributes;
    String name;

    public NamedStyle()
    {
      this(null, null);
    }

    public NamedStyle(Style parent)
    {
      this(null, parent);
    }

    public NamedStyle(String name, Style parent)
    {
      this.name = name;
      this.attributes = getEmptySet();
      this.changeEvent = new ChangeEvent(this);
      this.listenerList = new EventListenerList();
      setResolveParent(parent);
    }

    public String getName()
    {
      return name;
    }

    public void setName(String n)
    {
      name = n;
      fireStateChanged();
    }

    public void addChangeListener(ChangeListener l)
    {
      listenerList.add(ChangeListener.class, l);
    }
      
    public void removeChangeListener(ChangeListener l)
    {
      listenerList.remove(ChangeListener.class, l);
    }
      
    public EventListener[] getListeners(Class listenerType)
    {
      return listenerList.getListeners(listenerType);
    }

    public ChangeListener[] getChangeListeners()
    {
      return (ChangeListener[]) getListeners(ChangeListener.class);
    }

    protected  void fireStateChanged()
    {
      ChangeListener[] listeners = getChangeListeners();
      for (int i = 0; i < listeners.length; ++i)
        {
          listeners[i].stateChanged(changeEvent);
        }
    }

    public void addAttribute(Object name, Object value)
    {
      attributes = StyleContext.this.addAttribute(attributes, name, value);
      fireStateChanged();
    }

    public void addAttributes(AttributeSet attr)
    {
      attributes = StyleContext.this.addAttributes(attributes, attr);
      fireStateChanged();
    }

    public boolean containsAttribute(Object name, Object value)
    {
      return attributes.containsAttribute(name, value);
    }
      
    public boolean containsAttributes(AttributeSet attrs)
    {
      return attributes.containsAttributes(attrs);
    }

    public AttributeSet copyAttributes()
    {
      return attributes.copyAttributes();
    }
            
    public Object getAttribute(Object attrName)
    {
      return attributes.getAttribute(attrName);
    }

    public int getAttributeCount()
    {
      return attributes.getAttributeCount();
    }

    public Enumeration getAttributeNames()
    {
      return attributes.getAttributeNames();
    }
      
    public boolean isDefined(Object attrName)
    {
      return attributes.isDefined(attrName);        
    }

    public boolean isEqual(AttributeSet attr)
    {
      return attributes.isEqual(attr);
    }

    public void removeAttribute(Object name)
    {
      attributes = StyleContext.this.removeAttribute(attributes, name);
      fireStateChanged();
    }

    public void removeAttributes(AttributeSet attrs)
    {
      attributes = StyleContext.this.removeAttributes(attributes, attrs);
      fireStateChanged();
    }

    public void removeAttributes(Enumeration names)
    {
      attributes = StyleContext.this.removeAttributes(attributes, names);
      fireStateChanged();
    }


    public AttributeSet getResolveParent()
    {
      return attributes.getResolveParent();        
    }

    public void setResolveParent(AttributeSet parent)
    {
      attributes = StyleContext.this.addAttribute(attributes, ResolveAttribute, parent);
      fireStateChanged();
    }
      
    public String toString()
    {
      return ("[NamedStyle: name=" + name + ", attrs=" + attributes.toString() + "]");
    }      
  }
  
  public class SmallAttributeSet
    implements AttributeSet
  {
    final Object [] attrs;
    public SmallAttributeSet(AttributeSet a)
    {
      if (a == null)
        attrs = new Object[0];
      else
        {
          int n = a.getAttributeCount();
          int i = 0;
          attrs = new Object[n * 2];
          Enumeration e = a.getAttributeNames();
          while (e.hasMoreElements())
            {
              Object name = e.nextElement();
              attrs[i++] = name;
              attrs[i++] = a.getAttribute(name);
            }
        }
    }

    public SmallAttributeSet(Object [] a)
    {
      if (a == null)
        attrs = new Object[0];
      else
        {
          attrs = new Object[a.length];
          System.arraycopy(a, 0, attrs, 0, a.length);
        }
    }

    public Object clone()
    {
      return new SmallAttributeSet(this.attrs);
    }

    public boolean containsAttribute(Object name, Object value)
    {
      for (int i = 0; i < attrs.length; i += 2)
        {
          if (attrs[i].equals(name) &&
              attrs[i+1].equals(value))
            return true;
        }
      return false;
    }

    public boolean containsAttributes(AttributeSet a)
    {
      Enumeration e = a.getAttributeNames();
      while (e.hasMoreElements())
        {
          Object name = e.nextElement();
          Object val = a.getAttribute(name);
          if (!containsAttribute(name, val))
            return false;
        }
      return true;			
    }

    public AttributeSet copyAttributes()
    {
      return (AttributeSet) clone();
    }

    public boolean equals(Object obj)
    {
      return 
        (obj instanceof SmallAttributeSet)
        && this.isEqual((AttributeSet)obj);
    }
 
    public Object getAttribute(Object key)
    {
      for (int i = 0; i < attrs.length; i += 2)
        {
          if (attrs[i].equals(key))
            return attrs[i+1];
        }
            
      Object p = getResolveParent();
      if (p != null && p instanceof AttributeSet)
        return (((AttributeSet)p).getAttribute(key));
      
      return null;
    }

    public int getAttributeCount()
    {
      return attrs.length / 2;
    }

    public Enumeration getAttributeNames()
    {      
      return new Enumeration() 
        {
          int i = 0;
          public boolean hasMoreElements() 
          { 
            return i < attrs.length; 
          }
          public Object nextElement() 
          { 
            i += 2; 
            return attrs[i-2]; 
          }
        };
    }

    public AttributeSet getResolveParent()
    {
      return (AttributeSet) getAttribute(ResolveAttribute);
    }

    public int hashCode()
    {
      return java.util.Arrays.asList(attrs).hashCode();
    }

    public boolean isDefined(Object key)
    {
      for (int i = 0; i < attrs.length; i += 2)
        {
          if (attrs[i].equals(key))
            return true;
        }
      return false;
    }
	
    public boolean isEqual(AttributeSet attr)
    {
      return attr != null 
        && attr.containsAttributes(this)
        && this.containsAttributes(attr);
    }
	
    public String toString()
    {
      StringBuffer sb = new StringBuffer();
      sb.append("[StyleContext.SmallattributeSet:");
      for (int i = 0; i < attrs.length; ++i)
        {
          sb.append(" (");
          sb.append(attrs[i].toString());
          sb.append("=");
          sb.append(attrs[i+1].toString());
          sb.append(")");
        }
      sb.append("]");
      return sb.toString();
    }
  }

  // FIXME: official javadocs suggest that these might be more usefully
  // implemented using a WeakHashMap, but not sure if that works most
  // places or whether it really matters anyways.
  //
  // FIXME: also not sure if these tables ought to be static (singletons),
  // shared across all StyleContexts. I think so, but it's not clear in
  // docs. revert to non-shared if you think it matters.

  public static final String DEFAULT_STYLE = "default";
  
  static Hashtable sharedAttributeSets = new Hashtable();
  static Hashtable sharedFonts = new Hashtable();

  static StyleContext defaultStyleContext = new StyleContext();
  static final int compressionThreshold = 9;
  
  EventListenerList listenerList;
  Hashtable styleTable;
  
  public StyleContext()
  {
    listenerList = new EventListenerList();
    styleTable = new Hashtable();
  }

  protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
  {
    return new SmallAttributeSet(a);
  }
  
  protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
  {
    return new SimpleAttributeSet(a);
  }

  public void addChangeListener(ChangeListener listener)
  {
    listenerList.add(ChangeListener.class, listener);
  }

  public void removeChangeListener(ChangeListener listener)
  {
    listenerList.remove(ChangeListener.class, listener);
  }

  public ChangeListener[] getChangeListeners()
  {
    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
  }
    
  public Style addStyle(String name, Style parent)
  {
    Style newStyle = new NamedStyle(name, parent);
    if (name != null)
      styleTable.put(name, newStyle);
    return newStyle;
  }

  public void removeStyle(String name)
  {
    styleTable.remove(name);
  }

  public Style getStyle(String name)
  {
    return (Style) styleTable.get(name);
  }

  public Enumeration getStyleNames()
  {
    return styleTable.keys();
  }

  //
  // StyleContexts only understand the "simple" model of fonts present in
  // pre-java2d systems: fonts are a family name, a size (integral number
  // of points), and a mask of style parameters (plain, bold, italic, or
  // bold|italic). We have an inner class here called SimpleFontSpec which
  // holds such triples.
  //
  // A SimpleFontSpec can be built for *any* AttributeSet because the size,
  // family, and style keys in an AttributeSet have default values (defined
  // over in StyleConstants).
  //
  // We keep a static cache mapping SimpleFontSpecs to java.awt.Fonts, so
  // that we reuse Fonts between styles and style contexts.
  // 

  private static class SimpleFontSpec
  {
    String family;
    int style;
    int size;
    public SimpleFontSpec(String family,
                          int style,
                          int size)
    {
      this.family = family;
      this.style = style;
      this.size = size;
    }
    public boolean equals(Object obj)
    {
      return (obj != null)
        && (obj instanceof SimpleFontSpec)
        && (((SimpleFontSpec)obj).family.equals(this.family))
        && (((SimpleFontSpec)obj).style == this.style)
        && (((SimpleFontSpec)obj).size == this.size);
    }
    public int hashCode()
    {
      return family.hashCode() + style + size;
    }
  }
  
  public Font getFont(AttributeSet attr)
  {
    String family = StyleConstants.getFontFamily(attr);
    int style = Font.PLAIN;
    if (StyleConstants.isBold(attr))
      style += Font.BOLD;
    if (StyleConstants.isItalic(attr))
      style += Font.ITALIC;      
    int size = StyleConstants.getFontSize(attr);
    return getFont(family, style, size);
  }

  public Font getFont(String family, int style, int size)
  {
    SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
    if (sharedFonts.containsKey(spec))
      return (Font) sharedFonts.get(spec);
    else
      {
        Font tmp = new Font(family, style, size);
        sharedFonts.put(spec, tmp);
        return tmp;
      }
  }
  
  public FontMetrics getFontMetrics(Font f)
  {
    return Toolkit.getDefaultToolkit().getFontMetrics(f);
  }

  public Color getForeground(AttributeSet a)
  {
    return StyleConstants.getForeground(a);
  }

  public Color getBackground(AttributeSet a)
  {
    return StyleConstants.getBackground(a);
  }

  protected int getCompressionThreshold() 
  {
    return compressionThreshold;
  }

  public static StyleContext getDefaultStyleContext()
  {
    return defaultStyleContext;
  }

  public AttributeSet addAttribute(AttributeSet old, Object name, Object value)
  {
    if (old instanceof MutableAttributeSet)
      {
        ((MutableAttributeSet)old).addAttribute(name, value);
        return old;
      }
    else 
      {
        MutableAttributeSet mutable = createLargeAttributeSet(old);
        mutable.addAttribute(name, value);
        if (mutable.getAttributeCount() >= getCompressionThreshold())
          return mutable;
        else
          {
            SmallAttributeSet small = createSmallAttributeSet(mutable);
            if (sharedAttributeSets.containsKey(small))
              small = (SmallAttributeSet) sharedAttributeSets.get(small);
            else
              sharedAttributeSets.put(small,small);
            return small;
          }
      }
  }

  public AttributeSet addAttributes(AttributeSet old, AttributeSet attributes)
  {
    if (old instanceof MutableAttributeSet)
      {
        ((MutableAttributeSet)old).addAttributes(attributes);
        return old;
      }
    else 
      {
        MutableAttributeSet mutable = createLargeAttributeSet(old);
        mutable.addAttributes(attributes);
        if (mutable.getAttributeCount() >= getCompressionThreshold())
          return mutable;
        else
          {
            SmallAttributeSet small = createSmallAttributeSet(mutable);
            if (sharedAttributeSets.containsKey(small))
              small = (SmallAttributeSet) sharedAttributeSets.get(small);
            else
              sharedAttributeSets.put(small,small);
            return small;
          }
      }
  }

  public AttributeSet getEmptySet()
  {
    AttributeSet e = createSmallAttributeSet(null);
    if (sharedAttributeSets.containsKey(e))
      e = (AttributeSet) sharedAttributeSets.get(e);
    else
      sharedAttributeSets.put(e, e);
    return e;
  }

  public void reclaim(AttributeSet attributes)
  {
    if (sharedAttributeSets.containsKey(attributes))
      sharedAttributeSets.remove(attributes);
  }

  public AttributeSet removeAttribute(AttributeSet old, Object name)
  {
    if (old instanceof MutableAttributeSet)
      {
        ((MutableAttributeSet)old).removeAttribute(name);
        if (old.getAttributeCount() < getCompressionThreshold())
          {
            SmallAttributeSet small = createSmallAttributeSet(old);
            if (!sharedAttributeSets.containsKey(small))
              sharedAttributeSets.put(small,small);
            old = (AttributeSet) sharedAttributeSets.get(small);
          }
        return old;
      }
    else 
      {          
        MutableAttributeSet mutable = createLargeAttributeSet(old);
        mutable.removeAttribute(name);
        SmallAttributeSet small = createSmallAttributeSet(mutable);
        if (sharedAttributeSets.containsKey(small))
          small = (SmallAttributeSet) sharedAttributeSets.get(small);
        else
          sharedAttributeSets.put(small,small);
        return small;
      }
  }

  public AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes)
  {
    return removeAttributes(old, attributes.getAttributeNames());
  }

  public AttributeSet removeAttributes(AttributeSet old, Enumeration names)
  {
    if (old instanceof MutableAttributeSet)
      {
        ((MutableAttributeSet)old).removeAttributes(names);
        if (old.getAttributeCount() < getCompressionThreshold())
          {
            SmallAttributeSet small = createSmallAttributeSet(old);
            if (!sharedAttributeSets.containsKey(small))
              sharedAttributeSets.put(small,small);
            old = (AttributeSet) sharedAttributeSets.get(small);
          }
        return old;
      }
    else 
      {          
        MutableAttributeSet mutable = createLargeAttributeSet(old);
        mutable.removeAttributes(names);
        SmallAttributeSet small = createSmallAttributeSet(mutable);
        if (sharedAttributeSets.containsKey(small))
          small = (SmallAttributeSet) sharedAttributeSets.get(small);
        else
          sharedAttributeSets.put(small,small);
        return small;
      }	
  }


  // FIXME: there's some sort of quasi-serialization stuff in here which I
  // have left incomplete; I'm not sure I understand the intent properly.

  public static Object getStaticAttribute(Object key)
  {
    throw new InternalError("not implemented");
  }
  
  public static Object getStaticAttributeKey(Object key)
  {
    throw new InternalError("not implemented");
  }

  public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
    throws ClassNotFoundException, IOException
  {
    throw new InternalError("not implemented");
  }
  
  public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
    throws IOException
  {
    throw new InternalError("not implemented");
  }

  public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
    throws ClassNotFoundException, IOException 
  {
    throw new InternalError("not implemented");
  }

  public void writeAttributes(ObjectOutputStream out, AttributeSet a)
    throws IOException
  {
    throw new InternalError("not implemented");
  }
}
