package testlib.uno;

/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/

// __________ Imports __________

import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;

import com.sun.star.awt.Point;
import com.sun.star.awt.Size;

import com.sun.star.beans.XPropertySet;

import com.sun.star.container.NoSuchElementException;
import com.sun.star.container.XEnumeration;
import com.sun.star.container.XEnumerationAccess;
import com.sun.star.drawing.XDrawPage;
import com.sun.star.drawing.XDrawPages;
import com.sun.star.drawing.XDrawPagesSupplier;
import com.sun.star.drawing.XShape;
import com.sun.star.drawing.XShapes;

import com.sun.star.text.ControlCharacter;
import com.sun.star.text.XText;
import com.sun.star.text.XTextCursor;
import com.sun.star.text.XTextContent;
import com.sun.star.text.XTextRange;

public class ShapeUtil {
	// __________ static helper methods __________
	//
	public static XPropertySet createAndInsertShape(XComponent xDrawDoc,
			XShapes xShapes, Point aPos, Size aSize, String sShapeType)
			throws java.lang.Exception {
		XShape xShape = createShape(xDrawDoc, aPos, aSize, sShapeType);
		xShapes.add(xShape);
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(
				XPropertySet.class, xShape);
		return xPropSet;
	}

	/**
	 * create a Shape
	 */
	public static XShape createShape(XComponent xDrawDoc, Point aPos,
			Size aSize, String sShapeType) throws java.lang.Exception {
		XShape xShape = null;
		XMultiServiceFactory xFactory = (XMultiServiceFactory) UnoRuntime
				.queryInterface(XMultiServiceFactory.class, xDrawDoc);
		Object xObj = xFactory.createInstance(sShapeType);
		xShape = (XShape) UnoRuntime.queryInterface(XShape.class, xObj);
		xShape.setPosition(aPos);
		xShape.setSize(aSize);
		return xShape;
	}


	/**
	 * add text to a shape. the return value is the PropertySet of the text
	 * range that has been added
	 */
	public static XPropertySet addPortion(XShape xShape, String sText,
			boolean bNewParagraph)
			throws com.sun.star.lang.IllegalArgumentException {
		XText xText = (XText) UnoRuntime.queryInterface(XText.class, xShape);

		XTextCursor xTextCursor = xText.createTextCursor();
		xTextCursor.gotoEnd(false);
		if (bNewParagraph == true) {
			xText.insertControlCharacter(xTextCursor,
					ControlCharacter.PARAGRAPH_BREAK, false);
			xTextCursor.gotoEnd(false);
		}
		XTextRange xTextRange = (XTextRange) UnoRuntime.queryInterface(
				XTextRange.class, xTextCursor);
		xTextRange.setString(sText);
		xTextCursor.gotoEnd(true);
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(
				XPropertySet.class, xTextRange);
		return xPropSet;
	}
	
	/**
	 * get a paragraph in a shape. the return value is the PropertySet of the text
	 * range that specified by the index
	 */
	public static XPropertySet getPortion(XShape xShape, int index) throws NoSuchElementException, WrappedTargetException {
		XEnumerationAccess m_paraAccess = (XEnumerationAccess)UnoRuntime.queryInterface(XEnumerationAccess.class, xShape);
		XEnumeration xParaEnum = m_paraAccess.createEnumeration();	
		XPropertySet xPropSet = null;
		int i=0;
		while(xParaEnum.hasMoreElements())
		{
			if(i == index)
			{
				Object aPortionObj = xParaEnum.nextElement();
				XTextRange xTextRange = (XTextRange)UnoRuntime.queryInterface(XTextRange.class, aPortionObj);
//				System.out.println(xTextRange.getText().getString());
				xPropSet = (XPropertySet) UnoRuntime.queryInterface(
						XPropertySet.class, xTextRange);
				break;				
			}
			else i++;			
		}	
		return xPropSet;
	}


	/**
	 * try to get text of a shape
	 * 
	 * @return
	 */
	public static String getPortion(XShape xShape) {
		String text = null;
		XText xText = (XText) UnoRuntime.queryInterface(XText.class, xShape);

		XTextCursor xTextCursor = xText.createTextCursor();
		XTextRange xTextRange = (XTextRange) UnoRuntime.queryInterface(
				XTextRange.class, xTextCursor);
		text = xTextRange.getString();
		return text;

	}

	public static void setPropertyForLastParagraph(XShape xText,
			String sPropName, Object aValue)
			throws com.sun.star.beans.UnknownPropertyException,
			com.sun.star.beans.PropertyVetoException,
			com.sun.star.lang.IllegalArgumentException,
			com.sun.star.lang.WrappedTargetException,
			com.sun.star.container.NoSuchElementException {
		XEnumerationAccess xEnumerationAccess = (XEnumerationAccess) UnoRuntime
				.queryInterface(XEnumerationAccess.class, xText);
		if (xEnumerationAccess.hasElements()) {
			XEnumeration xEnumeration = xEnumerationAccess.createEnumeration();
			while (xEnumeration.hasMoreElements()) {
				Object xObj = xEnumeration.nextElement();
				if (xEnumeration.hasMoreElements() == false) {
					XTextContent xTextContent = (XTextContent) UnoRuntime
							.queryInterface(XTextContent.class, xObj);
					XPropertySet xParaPropSet = (XPropertySet) UnoRuntime
							.queryInterface(XPropertySet.class, xTextContent);
					xParaPropSet.setPropertyValue(sPropName, aValue);
				}
			}
		}
	}
	/**
	 * Get shapes in specific page
	 * @param impressDocument
	 * @param pageIndex
	 * @return
	 * @throws Exception
	 */
	public static XShapes getShapes(XComponent impressDocument, int pageIndex) throws Exception{

		XDrawPagesSupplier drawsupplier = (XDrawPagesSupplier) UnoRuntime.queryInterface(
				XDrawPagesSupplier.class, impressDocument);
		XDrawPages drawpages = drawsupplier.getDrawPages();
		XDrawPage xpage=(XDrawPage)UnoRuntime.queryInterface(XDrawPage.class, drawpages.getByIndex(pageIndex));
		XShapes xShapes = (XShapes) UnoRuntime.queryInterface(XShapes.class, xpage);
		return xShapes;

	}
	
	/**
	 * Remove the specific shape in specific page
	 * @param impressDocument
	 * @param pageIndex
	 * @param shapeIndex
	 * @throws Exception
	 */
	public static void removeOneShape(XComponent impressDocument, int pageIndex, int shapeIndex) throws Exception{
		XDrawPagesSupplier drawsupplier = (XDrawPagesSupplier) UnoRuntime.queryInterface(
				XDrawPagesSupplier.class, impressDocument);
		XDrawPages drawpages = drawsupplier.getDrawPages();
		XDrawPage xpage=(XDrawPage)UnoRuntime.queryInterface(XDrawPage.class, drawpages.getByIndex(pageIndex));
		XShapes xShapes = (XShapes) UnoRuntime.queryInterface(XShapes.class, xpage);
		XShape xShape = (XShape) UnoRuntime.queryInterface(XShape.class, xShapes.getByIndex(shapeIndex));
		xShapes.remove(xShape);

	}
}
