package com.mindoo.ec09.example5.ca.pb;

/*
 * Licensed Materials - Property of IBM
 * 
 * Lisence: 5724-E62 
 * 
 * (C) Copyright IBM Corp. 2007. All rights reserved.
 * 
 * IBM, the IBM logo, Lotus and Notes are trademarks of IBM Corporation
 * in the United States, other coutnries, or both. Other company,
 * product and service names may be trademarks or service marks
 * of others.
 * 
 * This program is licensed under the terms of the license agreement
 * accompanying the Program. This liscence agreement may be either 
 * located in a Program directory folder orlibrary identified as 
 * "License" or "Non IBM License", if applicable. Please read this 
 * agreement carefully before using the Program. By using the Program
 * you agree to these terms. 
 */

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.ui.IViewPart;

import com.ibm.rcp.propertybroker.property.Property;
import com.ibm.rcp.propertybroker.property.PropertyFactory;
import com.ibm.rcp.propertybroker.property.PropertyValue;
import com.ibm.rcp.propertybroker.service.PropertyBroker;
import com.ibm.rcp.propertybroker.service.PropertyBrokerException;
import com.ibm.rcp.propertybroker.service.PropertyBrokerFactory;
import com.mindoo.ec09.example5.ca.DebugUtils;
import com.mindoo.ec09.example5.ca.PCSBean;

public class PBBroadcast implements PropertyChangeListener
{
	public static boolean VERBOSE = false;
	
    private String mNamespaceRoot;
    
    private IViewPart		mView;
    private String          mPageName;
    private String          mPartName;
    private PropertyBroker  mBroker;
    private PCSBean         mBean;
    private HashMap         mCachedProperty;
    private boolean			mActive;
    private boolean			mOn;
    
    public PBBroadcast(IViewPart view, PCSBean bean)
    {
    	this(view, bean, "http://www.ibm.com/wps/c2a");
    }
    public PBBroadcast(IViewPart view, PCSBean bean, String namespace)
    {
        mNamespaceRoot = namespace;
    	mView = view;    	
        mBean = bean;
        mBroker = PropertyBrokerFactory.getBroker();
        mCachedProperty = new HashMap();
        setActive(true);
        setOn(true);
        mPageName = "";
    }
    
    public void dispose()
    {
    	setActive(false); 
    }
    
    private String shortName(Object o)
    {
        Class c;
        if (o instanceof Class)
            c = (Class)o;
        else
            c = o.getClass();
        String ret = c.getName();
        int off = ret.lastIndexOf(".");
        return ret.substring(off+1);
    }    
    
    private String makePropertyName(String propName)
    {
        StringBuffer ret = new StringBuffer("get");
        //ret.append(mBeanName);
        ret.append(Character.toUpperCase(propName.charAt(0)));
        ret.append(propName.substring(1));
        return ret.toString();
    }

    private Property getProperty(String propName) throws PropertyBrokerException
    {    	
        Property ret = null;
        if (mCachedProperty.containsKey(propName))
        	ret = (Property)mCachedProperty.get(propName);
        else
        {
        	for (StringTokenizer st = new StringTokenizer(mNamespaceRoot, ","); st.hasMoreTokens(); )
        	{
        		String ns = st.nextToken();
                ret = mBroker.getProperty(ns, makePropertyName(propName));
                if (ret != null)
                	break;
        	}
            if (ret == null)
                DebugUtils.println(shortName(this) +" propertyChange ignored, null property return for "+makePropertyName(propName)+".");
            mCachedProperty.put(propName, ret);
        }
        return ret;
    }
    
    public void propertyChange(PropertyChangeEvent evt)
    {
    	if (mPartName == null)
    	{	// lazy init
            mPartName = mView.getViewSite().getId();
            String secondaryID = mView.getViewSite().getSecondaryId(); 
            if (secondaryID != null)
                mPartName += ":"+secondaryID;
    	}
        try
        {
            String beanPropName = evt.getPropertyName();
            Property pbProp = getProperty(beanPropName);
            //XXX dbk debug of invalid NULL in constructor of PropertyValueImpl
        	if (pbProp == null)
                return;
            PropertyValue[] pbPropValues = new PropertyValue[1];
            Object newValue = evt.getNewValue();
            if (newValue == null)
            	newValue = "";
            pbPropValues[0] = PropertyFactory.createPropertyValue(pbProp, newValue);
            //DebugUtils.println("Firing "+makePropertyName(beanPropName)+"->"+evt.getNewValue()+" from "+DebugUtils.compressPackageName(mPartName));
            //DebugUtils.println("PBBroadcast="+hashCode()+", Bean="+mBean.hashCode());
            String newText = (evt.getNewValue() != null ? evt.getNewValue().toString() : "<null>");
            if (newText.length() > 128)
            	newText = newText.substring(0, 64) + " ... " + newText.substring(newText.length() - 64); 
            DebugUtils.println("PBBroadcast, "
            		+DebugUtils.getEntityProperty(mPageName, mPartName, makePropertyName(beanPropName))
            		+" = \""+newText+"\""
            		//+" (was \""+evt.getOldValue()+"\")"
            		);
            DebugUtils.println("  ns="+pbProp.getNamespace()+", type="+pbProp.getType());
            if (VERBOSE)
            {
            	Throwable t = new Throwable();
            	t.printStackTrace();
            }
            mBroker.changedProperties(pbPropValues, mPartName);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    public void fireAll()
    {
    	if (!mActive)
    		return;
    	Map vals = PBHandler.getValues(mBean);
    	for (Iterator i = vals.keySet().iterator(); i.hasNext(); )
    	{
    		String key = (String)i.next();
    		Object val = vals.get(key);
    		PropertyChangeEvent ev = new PropertyChangeEvent(mBean, key, val, val);
    		propertyChange(ev);
    	}
    }
	public boolean isActive() {
		return mActive;
	}
	public void setActive(boolean active) {
		mActive = active;
		mBean.removePropertyChangeListener(this);
		if (mActive && mOn)
	        mBean.addPropertyChangeListener(this);
	}
	public boolean isOn() {
		return mOn;
	}
	public void setOn(boolean on) {
		mOn = on;
		mBean.removePropertyChangeListener(this);
		if (mActive && mOn)
	        mBean.addPropertyChangeListener(this);
	}
	public String getPageName() {
		return mPageName;
	}
	public void setPageName(String pageName) {
		mPageName = pageName;
	}
	public PropertyBroker getBroker() {
		return mBroker;
	}
}
