/**************************************************************
 *
 * 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.
 *
 *************************************************************/

#include "vbachart.hxx"
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/script/BasicErrorException.hpp>
#include <basic/sberrors.hxx>
#include "vbachartobject.hxx"
#include "vbachartobjects.hxx"

using namespace ::com::sun::star;
using namespace ::ooo::vba;

const rtl::OUString CHART_NAME( RTL_CONSTASCII_USTRINGPARAM("Name") );
const rtl::OUString PERSIST_NAME( RTL_CONSTASCII_USTRINGPARAM("PersistName") );

ScVbaChartObject::ScVbaChartObject( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableChart >& _xTableChart, const css::uno::Reference< css::drawing::XDrawPageSupplier >& _xDrawPageSupplier ) : ChartObjectImpl_BASE( _xParent, _xContext ), xTableChart( _xTableChart ), xDrawPageSupplier( _xDrawPageSupplier )
{
    xDrawPage = xDrawPageSupplier->getDrawPage();
    xEmbeddedObjectSupplier.set( xTableChart, uno::UNO_QUERY_THROW );
    xNamed.set( xTableChart, uno::UNO_QUERY_THROW );
    sPersistName = getPersistName();
    xShape = setShape();
// #i121178#: don't set the persist name to the object but the OLE object's name(displaying name)
//    setName(sPersistName);
    setName(xNamed->getDisplayName());
    oShapeHelper.reset(new ShapeHelper(xShape));
}

rtl::OUString ScVbaChartObject::getPersistName()
{
	if ( !sPersistName.getLength() )
		sPersistName = xNamed->getName();
	return sPersistName;
}

uno::Reference< drawing::XShape >
ScVbaChartObject::setShape() throw ( script::BasicErrorException )
{
	try
	{
		sal_Int32 nItems = xDrawPage->getCount();
		for (int i = 0; i < nItems; i++)
		{
			xShape.set( xDrawPage->getByIndex(i), uno::UNO_QUERY_THROW );
			if (xShape->getShapeType().compareToAscii("com.sun.star.drawing.OLE2Shape") == 0 )
			{
				uno::Reference< beans::XPropertySet > xShapePropertySet(xShape, uno::UNO_QUERY_THROW );
				rtl::OUString sName;
				xShapePropertySet->getPropertyValue(PERSIST_NAME ) >>=sName;
				if ( sName.equals(sPersistName))
				{
					xNamedShape.set( xShape, uno::UNO_QUERY_THROW );
					return xShape;
				}
			}
		}
	}
	catch (uno::Exception& )
	{
		throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString() );
	}
	return NULL;
}

void SAL_CALL
ScVbaChartObject::setName( const rtl::OUString& sName ) throw (css::uno::RuntimeException)
{
	xNamedShape->setName(sName);
}

::rtl::OUString SAL_CALL
ScVbaChartObject::getName() throw (css::uno::RuntimeException)
{
	return xNamedShape->getName();
}

void SAL_CALL
ScVbaChartObject::Delete() throw ( css::script::BasicErrorException )
{
	// parent of this object is sheet
	uno::Reference< excel::XWorksheet > xParent( getParent(), uno::UNO_QUERY_THROW );
	uno::Reference< excel::XChartObjects > xColl( xParent->ChartObjects( uno::Any() ), uno::UNO_QUERY_THROW );
	ScVbaChartObjects* pChartObjectsImpl = static_cast< ScVbaChartObjects* >( xColl.get() );
	if (pChartObjectsImpl)
		pChartObjectsImpl->removeByName( getPersistName() );
	else
		throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent is not ChartObjects" ) ) );
}

void
ScVbaChartObject::Activate() throw ( script::BasicErrorException )
{
	try
	{
		// #TODO #FIXME should be ThisWorkbook or equivalent, or in
		// fact probably the chart object should be created with
		// the XModel owner
		//uno::Reference< view::XSelectionSupplier > xSelectionSupplier( getXModel().getCurrentController());
		uno::Reference< view::XSelectionSupplier > xSelectionSupplier( getCurrentExcelDoc(mxContext)->getCurrentController(), uno::UNO_QUERY_THROW );
		xSelectionSupplier->select(uno::makeAny(xShape));
	}
	catch (uno::Exception& )
	{
		throw script::BasicErrorException( rtl::OUString(), uno::Reference< uno::XInterface >(), SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ChartObject Activate internal error" ) ) );
	}
}

uno::Reference< excel::XChart > SAL_CALL
ScVbaChartObject::getChart() throw (css::uno::RuntimeException)
{
	return new ScVbaChart( this, mxContext, xEmbeddedObjectSupplier->getEmbeddedObject(), xTableChart );
}

rtl::OUString&
ScVbaChartObject::getServiceImplName()
{
	static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaChartObject") );
	return sImplName;
}

uno::Sequence< rtl::OUString >
ScVbaChartObject::getServiceNames()
{
	static uno::Sequence< rtl::OUString > aServiceNames;
	if ( aServiceNames.getLength() == 0 )
	{
		aServiceNames.realloc( 1 );
		aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.ChartObject" ) );
	}
	return aServiceNames;
}

double
ScVbaChartObject::getHeight()
{
	return oShapeHelper->getHeight();
}

void
ScVbaChartObject::setHeight(double _fheight) throw ( script::BasicErrorException )
{
	oShapeHelper->setHeight(_fheight);
}

double
ScVbaChartObject::getWidth()
{
        return oShapeHelper->getWidth();
}

void
ScVbaChartObject::setWidth(double _fWidth) throw ( script::BasicErrorException )
{
	oShapeHelper->setWidth(_fWidth);
}

double
ScVbaChartObject::getLeft()
{
        return oShapeHelper->getLeft();
}

void
ScVbaChartObject::setLeft(double _fLeft)
{
	oShapeHelper->setLeft(_fLeft);
}

double
ScVbaChartObject::getTop()
{
        return oShapeHelper->getTop();
}

void
ScVbaChartObject::setTop(double _fTop)
{
	oShapeHelper->setTop(_fTop);
}

uno::Reference< uno::XInterface >
ScVbaChartObject::getUnoObject() throw (script::BasicErrorException)
{
	return uno::Reference< uno::XInterface >( xShape, uno::UNO_QUERY );
}
