/* ZKUDFFinder.java

	Purpose:
		
	Description:
		
	History:
		Apr 6, 2010 4:54:57 PM, Created by henrichen

Copyright (C) 2010 Potix Corporation. All Rights Reserved.

*/

package org.zkoss.zssex.formula;

import java.util.HashMap;
import java.util.Map;

import org.zkoss.poi.ss.formula.OperationEvaluationContext;
import org.zkoss.poi.ss.formula.UserDefinedFunction;
import org.zkoss.poi.ss.formula.eval.ErrorEval;
import org.zkoss.poi.ss.formula.eval.ValueEval;
import org.zkoss.poi.ss.formula.functions.FreeRefFunction;
import org.zkoss.poi.ss.formula.udf.UDFFinder;
import org.zkoss.zssex.formula.ELEval;
import org.zkoss.zssex.formula.ZKUDFFinder;

/**
 * User defined function finder for ZK.
 * @author henrichen
 * @author dennischen
 */
public class ZKUDFFinder implements UDFFinder {
	private static Map<String, FreeRefFunction> FNS = new HashMap<String, FreeRefFunction>(3);
	private static final FreeRefFunction UNSUPPORTED_FUNCTION = new FreeRefFunction() {
		public ValueEval evaluate(ValueEval[] args,
				OperationEvaluationContext ec) {
			return ErrorEval.NAME_INVALID;
		}
	};
	static {
		// zk internal function
		FNS.put(ELEval.NAME, ELEval.instance);
		
		//override unsupported formulas for they throw not-implemented exception in POI
		//date time
		FNS.put("EDATE", UNSUPPORTED_FUNCTION);
//		FNS.put("EOMONTH", UNSUPPORTED_FUNCTION); //ZSS-1014
		FNS.put("WEEKNUM", UNSUPPORTED_FUNCTION);
		//financial
		FNS.put("MDURATION", UNSUPPORTED_FUNCTION);
		FNS.put("ODDFPRICE", UNSUPPORTED_FUNCTION);
		FNS.put("ODDFYIELD", UNSUPPORTED_FUNCTION);
		FNS.put("ODDLPRICE", UNSUPPORTED_FUNCTION);
		FNS.put("ODDLYIELD", UNSUPPORTED_FUNCTION);
		FNS.put("XIRR", UNSUPPORTED_FUNCTION);
		//engineering
		FNS.put("CONVERT", UNSUPPORTED_FUNCTION);
		//math
		FNS.put("SERIESSUM", UNSUPPORTED_FUNCTION);
		//statistical
		FNS.put("AVERAGEIF", UNSUPPORTED_FUNCTION);
		FNS.put("AVERAGEIFS", UNSUPPORTED_FUNCTION);
		FNS.put("COUNTIFS", UNSUPPORTED_FUNCTION);
		//text
		FNS.put("BAHTTEXT", UNSUPPORTED_FUNCTION);
		FNS.put("PHONETIC", UNSUPPORTED_FUNCTION);
		FNS.put("JIS", UNSUPPORTED_FUNCTION);
	}
	public static final UDFFinder instance = new ZKUDFFinder();

	private ZKUDFFinder() {
		// enforce singleton
	}
	
	@Override
	public FreeRefFunction findFunction(String name) {
		if (name != null && name.startsWith("_xlfn.")) {
			name = name.substring(6);
		}
		FreeRefFunction fn = FNS.get(name);
		if(fn==null){
			fn = new ELEvalFunction(name);
			//if no such function in el eval context
			if(!((ELEvalFunction)fn).hasFunction()){
				return null;
			}
		}
		return fn;
	}
}
