// Copyright 2004, FreeHEP.
package hep.graphics.heprep1.adapter;

import java.awt.*;
import java.util.*;
import java.util.regex.*;

import hep.graphics.heprep.HepRep;
import hep.graphics.heprep.HepRepAttValue;
import hep.graphics.heprep.HepRepAttDef;
import hep.graphics.heprep.HepRepInstance;
import hep.graphics.heprep.HepRepPoint;
import hep.graphics.heprep.HepRepType;
import hep.graphics.heprep.ref.DefaultHepRepAttValue;
import hep.graphics.heprep.util.HepRepColor;
import hep.graphics.heprep.xml.XMLHepRepFactory;

/**
 *
 * @author Mark Donszelmann
 * @version $Id: HepRepAdapterFactory.java,v 1.4 2004/07/30 14:51:52 duns Exp $
 */
public class HepRepAdapterFactory extends XMLHepRepFactory {

    private static HepRepAdapterFactory factory;
    private static Map/*<String, Map<String, String> >*/ valueTranslator;
    static {
        // FIXME, more translations
        // NOTE: lowercase keys
        Map poly = new HashMap();
        poly.put("polypoint",   "Point");
        poly.put("polyline",    "Line");
        
        Map fonts = new HashMap();
        fonts.put("arial",      "SansSerif");
        fonts.put("helvetica",  "SansSerif");
        fonts.put("times",      "Serif");
        fonts.put("courrier",   "MonoSpaced");
        
        // NOTE: lowercase keys
        valueTranslator = new HashMap();
        valueTranslator.put("drawas",               poly);
        valueTranslator.put("drawasoptions",        poly);
        valueTranslator.put("fontname",             fonts);
    }

    private HepRepAdapterFactory() {
    }

    public static HepRepAdapterFactory getFactory() {
        if (factory == null) {
            factory = new HepRepAdapterFactory();
        }
        return factory;
    }

    public HepRep createHepRep(hep.graphics.heprep1.HepRep heprep1) {
        return new HepRepAdapter(heprep1);
    }

    public HepRepAttValue createHepRepAttValue(hep.graphics.heprep1.HepRepAttValue value1) {
        if (value1 == null) return null;
         
        String name = AttributeNameTranslator.getName2(value1.getName());

        // FIXME get type in a different way if possible
        String type = DefaultHepRepAttValue.guessType(name, value1.getString(), null);
        int typeCode = DefaultHepRepAttValue.toType(type);
        
        switch (typeCode) {
            case HepRepAttValue.TYPE_COLOR:
                return new HepRepAttValueAdapter(value1, name, HepRepColor.get(value1.getString()), value1.showLabel());
            case HepRepAttValue.TYPE_LONG:
                return new HepRepAttValueAdapter(value1, name, value1.getLong(), value1.showLabel());
            case HepRepAttValue.TYPE_INT:
                return new HepRepAttValueAdapter(value1, name, value1.getInteger(), value1.showLabel());
            case HepRepAttValue.TYPE_DOUBLE:
                return new HepRepAttValueAdapter(value1, name, value1.getDouble(), value1.showLabel());
            case HepRepAttValue.TYPE_BOOLEAN:
                return new HepRepAttValueAdapter(value1, name, value1.getBoolean(), value1.showLabel());
            case HepRepAttValue.TYPE_STRING:
                String s = value1.getString();
                Map translations = (Map)valueTranslator.get(name.toLowerCase());
                if (translations != null) {
                    for (Iterator i=translations.keySet().iterator(); i.hasNext(); ) {
                        String key = (String)i.next();
                        String value = (String)translations.get(key);
    	                Pattern pattern = Pattern.compile(key, Pattern.CASE_INSENSITIVE);
    	                s = pattern.matcher(s).replaceAll(value);
                    }
                }
                return new HepRepAttValueAdapter(value1, name, s, value1.showLabel());
            default:
                System.err.println("Unknown type in DefaultHepRepAttValue: '"+type+"'");
                return new HepRepAttValueAdapter(value1, name, value1.getString(), value1.showLabel());
         }
    }

    public HepRepAttDef createHepRepAttDef(hep.graphics.heprep1.HepRepAttDef def1) {
        if (def1 == null) return null;
        return new HepRepAttDefAdapter(def1, 
                                       AttributeNameTranslator.getName2(def1.getName()),
                                       def1.getDescription(),
                                       def1.getType(),
                                       def1.getExtra());
    }

    public HepRepType createHepRepType(hep.graphics.heprep1.HepRep heprep1, HepRepType parent) {
        return new HepRepTypeFromHepRepAdapter(heprep1, parent);
    }

    public HepRepType createHepRepType(hep.graphics.heprep1.HepRepType type1, HepRepType parent, HepRepInstance instance) {
        return new HepRepTypeFromTypeAdapter(type1, parent, instance);
    }

    public HepRepType createHepRepType(hep.graphics.heprep1.HepRepType type1, hep.graphics.heprep1.HepRepInstance instance1, HepRepType parent, HepRepInstance instance, String suffix) {
        return new HepRepTypeFromInstanceAdapter(type1, instance1, parent, instance, suffix);
    }

    public HepRepInstance createHepRepInstance(hep.graphics.heprep1.HepRep heprep1, HepRepInstance parent, HepRepType type) {
        return new HepRepInstanceFromHepRepAdapter(heprep1, parent, type);
    }

    public HepRepInstance createHepRepInstance(hep.graphics.heprep1.HepRepInstance instance1, HepRepInstance parent, HepRepType type) {
        return new HepRepInstanceFromInstanceAdapter(instance1, parent, type);
    }

    public HepRepInstance createHepRepInstance(hep.graphics.heprep1.HepRepInstance instance1, hep.graphics.heprep1.HepRepPrimitive primitive1, HepRepInstance parent, HepRepType type) {
        return new HepRepInstanceFromPrimitiveAdapter(instance1, primitive1, parent, type);
    }

    public HepRepPoint createHepRepPoint(hep.graphics.heprep1.HepRepPoint point1, HepRepInstance parent) {
        return new HepRepPointAdapter(point1, parent);
    }

//    public HepRepInstance createHepRepInstance(hep.graphics.heprep1.HepRepType type1, HepRepInstance parent, HepRepType type) {
//        return new HepRepInstanceFromTypeAdapter(type1, parent, type);
//    }

//    public HepRepInstance createHepRepInstanceFromPoints(hep.graphics.heprep1.HepRepType type1, HepRepInstance parent, HepRepType type) {
//        return new HepRepInstanceFromPointAdapter(type1, parent, type);
//    }

//    public HepRepInstance createHepRepInstanceFromPoints(hep.graphics.heprep1.HepRepInstance instance1, HepRepInstance parent, HepRepType type) {
//        return new HepRepInstanceFromPointAdapter(instance1, parent, type);
//    }
}