/*******************************************************************************
 * Copyright (c) 2005, 2010 Andrea Bittau, University College London, and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Andrea Bittau - initial API and implementation from the PsychoPath XPath 2.0
 *     David Carver (STAR) - bug 280972 - fix fn:lang implementation so it matches spec. 
 *     Jesper Steen Moeller - bug 285145 - implement full arity checking
 *     David Carver (STAR) - bug 262765 - correct invalidType to throw XPTY0004 instead of FORG0006
 *     Mukul Gandhi - bug 280798 - PsychoPath support for JDK 1.4
 *******************************************************************************/

package org.eclipse.wst.xml.xpath2.processor.internal.function;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.wst.xml.xpath2.api.EvaluationContext;
import org.eclipse.wst.xml.xpath2.api.ResultSequence;
import org.eclipse.wst.xml.xpath2.processor.DynamicError;
import org.eclipse.wst.xml.xpath2.processor.internal.SeqType;
import org.eclipse.wst.xml.xpath2.processor.internal.types.AnyType;
import org.eclipse.wst.xml.xpath2.processor.internal.types.NodeType;
import org.eclipse.wst.xml.xpath2.processor.internal.types.QName;
import org.eclipse.wst.xml.xpath2.processor.internal.types.XSBoolean;
import org.eclipse.wst.xml.xpath2.processor.internal.types.XSString;
import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * This function tests whether the language of $node, or the context node if the
 * second argument is omitted, as specified by xml:lang attributes is the same
 * as, or is a sublanguage of, the language specified by $testlang. The language
 * of the argument node, or the context node if the second argument is omitted,
 * is determined by the value of the xml:lang attribute on the node, or, if the
 * node has no such attribute, by the value of the xml:lang attribute on the
 * nearest ancestor of the node that has an xml:lang attribute. If there is no
 * such ancestor, then the function returns false.
 */
public class FnLang extends Function {
	private static Collection _expected_args = null;

	/**
	 * Constructor for FnLang.
	 */
	public FnLang() {
		super(new QName("lang"), 1, 2);
	}

	/**
	 * Evaluate arguments.
	 * 
	 * @param args
	 *            argument expressions.
	 * @throws DynamicError
	 *             Dynamic error.
	 * @return Result of evaluation.
	 */
	public ResultSequence evaluate(Collection args, EvaluationContext ec) throws DynamicError {
		return lang(args, ec);
	}

	/**
	 * Language operation.
	 * 
	 * @param args
	 *            Result from the expressions evaluation.
	 * @throws DynamicError
	 *             Dynamic error.
	 * @return Result of fn:lang operation.
	 */
	public static ResultSequence lang(Collection args, EvaluationContext ec) throws DynamicError {

		Collection cargs = Function.convert_arguments(args, expected_args());

		// get arg
		Iterator citer = cargs.iterator();
		ResultSequence arg1 = (ResultSequence) citer.next();
		ResultSequence arg2 = null;
		if (cargs.size() == 1) {
			if (ec.getContextItem() == null) {
				throw DynamicError.contextUndefined();
			}
			arg2 = (AnyType) ec.getContextItem();
		} else {
			arg2 = (ResultSequence) citer.next();
		}
		
		String lang = "";

		if (!arg1.empty()) {
			lang = ((XSString) arg1.first()).value();
		}

		
		if (!(arg2.first() instanceof NodeType) ) {
			throw DynamicError.invalidType();
		}
		
		NodeType an = (NodeType) arg2.first();

		return new XSBoolean(test_lang(an.node_value(), lang));
	}

	/**
	 * Language test operation.
	 * 
	 * @param node
	 *            Node to test.
	 * @param lang
	 *            Language to test for.
	 * @return Boolean result of operation.
	 */
	private static boolean test_lang(Node node, String lang) {
		NamedNodeMap attrs = node.getAttributes();

		if (attrs != null) {
			for (int i = 0; i < attrs.getLength(); i++) {
				Attr attr = (Attr) attrs.item(i);

				if (!"xml:lang".equals(attr.getName()))
					continue;
				
				String xmllangValue = attr.getValue();
				int hyphenIndex = xmllangValue.indexOf('-');
				
				if (hyphenIndex > -1) {
					xmllangValue = xmllangValue.substring(0, hyphenIndex);
				}

				
				String langLanguage = lang;
				if (lang.length() > 2) {
					langLanguage = lang.substring(0, 2);
				}
				
				return xmllangValue.equalsIgnoreCase(langLanguage);
			}
		}

		Node parent = node.getParentNode();
		if (parent == null)
			return false;

		return test_lang(parent, lang);
	}

	/**
	 * Obtain a list of expected arguments.
	 * 
	 * @return Result of operation.
	 */
	public synchronized static Collection expected_args() {
		if (_expected_args == null) {
			_expected_args = new ArrayList();

			_expected_args.add(new SeqType(new XSString(), SeqType.OCC_QMARK));
			_expected_args.add(new SeqType(SeqType.OCC_NONE));
		}

		return _expected_args;
	}
		
}
