/*******************************************************************************
 * Copyright (c) 2007 IBM Corporation 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:
 *    Hisashi MIYASHITA - initial API and implementation
 *    Kentarou FUKUDA - initial API and implementation
 *******************************************************************************/

package org.eclipse.actf.model.dom.dombycom.impl.flash;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

import org.eclipse.actf.model.dom.dombycom.AnalyzedResult;
import org.eclipse.actf.model.dom.dombycom.IFlashMSAANode;
import org.eclipse.actf.model.dom.dombycom.IFlashNode;
import org.eclipse.actf.model.dom.dombycom.INodeEx;
import org.eclipse.actf.model.dom.dombycom.impl.DocumentImpl;
import org.eclipse.actf.model.flash.ASAccInfo;
import org.eclipse.actf.model.flash.IASBridge;
import org.eclipse.actf.model.flash.IASNode;
import org.eclipse.actf.model.flash.IFlashConst;
import org.eclipse.actf.util.dom.EmptyNodeListImpl;
import org.eclipse.actf.util.vocab.AbstractTerms;
import org.eclipse.actf.util.win32.comclutch.ComPlugin;
import org.eclipse.actf.util.win32.keyhook.ISendEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.UserDataHandler;

class FlashNodeImpl implements IFlashNode, IFlashConst {
	// final ASObject nodeASObj;
	private final ASAccInfo accInfo;
	private final String target;
	private final IFlashNode parent;
	private final boolean hasChildren;
	private FlashTopNodeImpl swf;
	private DocumentImpl doc;

	private final IASNode flashNode;
	private final IASBridge flashPlayer;

	@Override
	public int hashCode() {
		return this.target.intern().hashCode();
	}

	@Override
	public boolean equals(Object o) {
		if (o instanceof FlashNodeImpl) {
			FlashNodeImpl f = (FlashNodeImpl) o;
			return swf.equals(f.swf) && this.target.equals(f.target);
		}
		return false;
	}

	private FlashNodeImpl(IASNode node, IFlashNode parent) {
		this.flashNode = node;
		this.flashPlayer = node.getPlayer();
		this.target = node.getTarget();
		this.accInfo = node.getAccInfo();
		if (node.isOpaqueObject()) {
			this.hasChildren = false;
		} else {
			this.hasChildren = true;
		}
		this.parent = parent;
	}

	FlashNodeImpl(FlashNodeImpl baseNode, IASNode node) {
		this(node, baseNode);
		this.swf = baseNode.swf;
		this.doc = baseNode.doc;
	}

	FlashNodeImpl(FlashTopNodeImpl baseNode, IASNode node) {
		this(node, baseNode);
		this.swf = baseNode;
		this.doc = (DocumentImpl) baseNode.getOwnerDocument();
	}

	private Object getProperty(String prop) {
		return flashPlayer.getProperty(getTarget(), prop);
	}

	private void setProperty(String prop, Object value) {
		flashPlayer.setProperty(getTarget(), prop, value);
	}

	private static ISendEvent sendEvent;

	private ISendEvent getSendEvent() {
		if (sendEvent == null) {
			sendEvent = ComPlugin.getDefault().newSendEvent();
		}
		return sendEvent;
	}

	public String getNodeName() {
		return "#flashNode:" + getTarget();
	}

	public String getNodeValue() throws DOMException {
		return null;
	}

	public void setNodeValue(String nodeValue) throws DOMException {
		throw new UnsupportedOperationException();
	}

	public short getNodeType() {
		// return FLASH_NODE;
		return Node.ELEMENT_NODE;
	}

	public Node getParentNode() {
		return parent;
	}

	private static class NodeListImpl implements NodeList {
		private final IFlashNode[] nodes;

		public Node item(int index) {
			if ((index < 0) || (index >= nodes.length))
				return null;
			return nodes[index];
		}

		public int getLength() {
			return nodes.length;
		}

		NodeListImpl(IFlashNode[] nodes) {
			this.nodes = nodes;
		}
	}

	public NodeList getChildNodes() {
		if (!hasChildren)
			return EmptyNodeListImpl.getInstance();
		IFlashNode[] r = getSWFChildNodes();
		return new NodeListImpl(r);
	}

	public Node getFirstChild() {
		if (!hasChildren)
			return null;
		IFlashNode[] r = getSWFChildNodes();
		if (r == null)
			return null;
		if (r.length == 0)
			return null;
		return r[0];
	}

	public Node getLastChild() {
		if (!hasChildren)
			return null;
		IFlashNode[] r = getSWFChildNodes();
		if (r == null)
			return null;
		if (r.length == 0)
			return null;
		return r[r.length - 1];
	}

	public Node getPreviousSibling() {
		throw new UnsupportedOperationException();
	}

	public Node getNextSibling() {
		throw new UnsupportedOperationException();
	}

	public NamedNodeMap getAttributes() {
		return null;
	}

	public Document getOwnerDocument() {
		return doc;
	}

	public Node insertBefore(Node newChild, Node refChild) throws DOMException {
		throw new UnsupportedOperationException();
	}

	public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
		throw new UnsupportedOperationException();
	}

	public Node removeChild(Node oldChild) throws DOMException {
		throw new UnsupportedOperationException();
	}

	public Node appendChild(Node newChild) throws DOMException {
		throw new UnsupportedOperationException();
	}

	public boolean hasChildNodes() {
		// IFlashNode[] r = getInnerNodes();
		if (!hasChildren)
			return false;
		IFlashNode[] r = getSWFChildNodes();
		if (r == null)
			return false;
		if (r.length == 0)
			return false;
		return true;
	}

	public Node cloneNode(boolean deep) {
		throw new UnsupportedOperationException();
	}

	public void normalize() {
	}

	public boolean isSupported(String feature, String version) {
		return false;
	}

	public String getNamespaceURI() {
		return null;
	}

	public String getPrefix() {
		return null;
	}

	public void setPrefix(String prefix) throws DOMException {
		throw new UnsupportedOperationException();
	}

	public String getLocalName() {
		String target = getTarget();
		int idx = target.lastIndexOf('.');
		if (idx < 0)
			return target;
		return target.substring(idx + 1);
	}

	public boolean hasAttributes() {
		return false;
	}

	public String getBaseURI() {
		return null;
	}

	public short compareDocumentPosition(Node other) throws DOMException {
		return 0;
	}

	public String getTextContent() throws DOMException {
		return extractString();
	}

	public void setTextContent(String textContent) throws DOMException {
		throw new UnsupportedOperationException();
	}

	public boolean isSameNode(Node other) {
		return false;
	}

	public String lookupPrefix(String namespaceURI) {
		return null;
	}

	public boolean isDefaultNamespace(String namespaceURI) {
		return false;
	}

	public String lookupNamespaceURI(String prefix) {
		return null;
	}

	public boolean isEqualNode(Node arg) {
		return false;
	}

	public Object getFeature(String feature, String version) {
		return null;
	}

	public Object setUserData(String key, Object data, UserDataHandler handler) {
		throw new UnsupportedOperationException();
	}

	public Object getUserData(String key) {
		throw new UnsupportedOperationException();
	}

	// --------------------------------------------------------------------------------
	// INodeEx interface
	// --------------------------------------------------------------------------------

	@SuppressWarnings("unused")
	private String decodeString(String input) {
		if (input == null)
			return "";
		try {
			return URLDecoder.decode(input, "UTF-8");
		} catch (UnsupportedEncodingException e) {
		}
		return input;
	}

	public String extractString() {
		String r = null;
		if (null != accInfo) {
			accInfo.getName();
		}
		if (r == null) {
			r = flashNode.getText(false);
		}
		if (r == null)
			return "";
		// return decodeString(r);
		return r;
	}

	public short getHeadingLevel() {
		return 0;
	}

	public String getLinkURI() {
		// TODO
		return null;
	}

	public void setText(String text) {
		setProperty(ASNODE_TEXT, text);
	}

	public String getText() {
		Object o = getProperty(ASNODE_TEXT);
		if (o instanceof String)
			return (String) o;
		return "";
	}

	private boolean doHardwareClick() {
		long hwnd = swf.getHWND();
		int ix = (int) flashNode.getX();
		int iy = (int) flashNode.getY();
		int iw = (int) flashNode.getWidth();
		int ih = (int) flashNode.getHeight();
		int x = ix + iw / 4;
		int y = iy + ih / 4;

		// System.err.println("Click to:" + x + "," + y);

		// getSendEvent().postMouse(x, y, false);
		getSendEvent().focusWindow(hwnd);
		setFocus();
		getSendEvent().postMouse(x, y, false);
		boolean result = getSendEvent().postMouse(x, y, true);
		return result;
	}

	String getClickableTarget(String current) {
		while (current.length() > 0) {
			String tryOnRelease = current + PATH_ON_RELEASE;
			if (swf.getNodeFromPath(tryOnRelease) != null) {
				return current;
			}
			String tryOnPress = current + PATH_ON_PRESS;
			if (swf.getNodeFromPath(tryOnPress) != null) {
				return current;
			}
			int idx = current.lastIndexOf('.');
			if (idx <= 0)
				break;
			current = current.substring(0, idx);
		}
		return null;
	}

	public boolean doClick() {
		String current = getTarget();
		while (current.length() > 0) {
			String tryOnRelease = current + PATH_ON_RELEASE;
			if (swf.getNodeFromPath(tryOnRelease) != null) {
				flashPlayer.callMethod(flashNode, M_ON_RELEASE);
				return true;
			}
			String tryOnPress = current + PATH_ON_PRESS;
			if (swf.getNodeFromPath(tryOnPress) != null) {
				flashPlayer.callMethod(flashNode, M_ON_PRESS);
				return true;
			}
			if (true)
				break;
			int idx = current.lastIndexOf('.');
			if (idx <= 0)
				break;
			current = current.substring(0, idx);
		}
		if (doHardwareClick())
			return true;
		return false;
	}

	public boolean highlight() {
		flashPlayer.callMethod(flashNode, M_ON_ROLL_OVER);
		boolean ret1 = swf.highlight();
		boolean ret2 = flashNode.setMarker();
		return ret1 && ret2;
	}

	public boolean unhighlight() {
		flashPlayer.callMethod(flashNode, M_ON_ROLL_OUT);
		boolean ret1 = swf.unhighlight();
		boolean ret2 = flashPlayer.unsetMarker();
		return ret1 && ret2;
	}

	public boolean setFocus() {
		if (!swf.setFocus())
			return false;
		return flashPlayer.setFocus(getTarget());
	}

	public int getNth() {
		// TODO!
		return 0;
	}

	// --------------------------------------------------------------------------------
	// IFlashNode interface
	// --------------------------------------------------------------------------------

	public String getTarget() {
		return target;
	}

	public IFlashNode getNodeFromPath(String path) {
		return swf.getNodeFromPath(path);
	}

	public IFlashNode getNodeAtDepth(int depth) {
		IASNode result = flashPlayer.getNodeAtDepthWithPath(getTarget(), depth);
		if (result == null)
			return null;
		return new FlashNodeImpl(swf, result);
	}

	private IFlashNode[] createIFlashNodeArray(IASNode[] nodes) {
		IFlashNode[] results = new IFlashNode[nodes.length];
		for (int i = 0; i < nodes.length; i++) {
			results[i] = new FlashNodeImpl(this, nodes[i]);
		}
		return results;
	}

	public IFlashNode[] getInnerNodes() {
		return createIFlashNodeArray(flashNode.getChildren(true));
	}

	public IFlashNode[] getSWFChildNodes() {
		return createIFlashNodeArray(flashNode.getChildren(false));
	}

	public int getDepth() {
		return flashNode.getDepth();
	}

	public int getCurrentFrame() {
		return flashNode.getCurrentFrame();
	}

	public IFlashNode[] translate() {
		return createIFlashNodeArray(flashPlayer.translateWithPath(getTarget()));
	}

	public INodeEx getBaseNode() {
		return swf;
	}

	// --------------------------------------------------------------------------------
	// extensions.
	// --------------------------------------------------------------------------------

	boolean isInputable() {
		return flashNode.isInputable();
	}

	boolean isSilent() {
		return accInfo.isSilent();
	}

	public AnalyzedResult analyze(AnalyzedResult ar) {
		return ar;
	}

	public AbstractTerms getTerms() {
		return FlashTerms.getInstance();
	}

	public Rectangle getLocation() {
		// TODO
		return swf.getLocation();
	}

	// --------------------------------------------------------------------------------
	// Dummy
	// --------------------------------------------------------------------------------
	public IFlashMSAANode getMSAA() {
		return null;
	}

	public void repairFlash() {
	}

	// !FN!
	public String[] getStillPictureData() {
		return new String[3];
	}

	public char getAccessKey() {
		return 0;
	}

}
