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



import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.FrameSearchFlag;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XDispatch;
import com.sun.star.frame.XDispatchProvider;
import com.sun.star.frame.XFrame;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.reflection.TypeDescriptionSearchDepth;
import com.sun.star.reflection.XServiceTypeDescription;
import com.sun.star.reflection.XTypeDescription;
import com.sun.star.reflection.XTypeDescriptionEnumeration;
import com.sun.star.reflection.XTypeDescriptionEnumerationAccess;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Type;
import com.sun.star.uno.TypeClass;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.URL;
import com.sun.star.util.XURLTransformer;
import java.util.List;
import java.util.Vector;

public class UnoNode{

    String sPath = null;
    Object m_oUnoObject;
    private XMultiComponentFactory m_xMultiComponentFactory;
    private XComponentContext m_xComponentContext;
    private Object[] m_oParamObjects = null;
    private int m_nNodeType = XUnoNode.nOTHERS;
    private Type aType = null;
    private String sLabel = "";



    /** Creates a new instance of UnoNode */
    public UnoNode(Object _oUnoObject) {
        m_xComponentContext = Introspector.getIntrospector().getXComponentContext();
        m_xMultiComponentFactory = m_xComponentContext.getServiceManager();
        m_oUnoObject = _oUnoObject;
    }

    public UnoNode(Object _oUnoObject, Type _aType) {
        this(_oUnoObject);
        aType = _aType;
        m_nNodeType = XUnoNode.nINTERFACE;
    }

    public Object getUnoObject(){
        return m_oUnoObject;
    }


    protected XComponentContext getXComponentContext(){
        return m_xComponentContext;
    }


    protected XMultiComponentFactory getXMultiComponentFactory(){
        return m_xMultiComponentFactory;
    }


    private static XTypeDescriptionEnumerationAccess getXTypeDescriptionEnumerationAccess(){
       return Introspector.getIntrospector().getXTypeDescriptionEnumerationAccess();
    }


    public String getAnchor(){
        return "";
    }

    public int getNodeType(){
        return m_nNodeType;
    }

    public void setNodeType(int _nNodeType){
        m_nNodeType = _nNodeType;
    }

    public String getClassName(){
        String sClassName = "";
        if (m_nNodeType == XUnoNode.nINTERFACE){
            sClassName = aType.getTypeName();
        }
        else if(m_nNodeType == XUnoNode.nSERVICE){
            sClassName = sLabel;
        }
        return sClassName;
    }


    public Type getUnoType(){
        return aType;
    }

    protected void  setLabel(String _sLabel){
        sLabel = _sLabel;
    }

    public void openIdlDescription(String _sIDLUrl, String _sClassName, String _sAnchor){
    try{
        String sIDLUrl = _sIDLUrl;
        String sAnchor = ""; // TODO find out how the Anchor may be set at the HTML file;  //_sAnchor;
        boolean bExists = Introspector.getIntrospector().getXSimpleFileAccess().exists(sIDLUrl);
        if (sIDLUrl.equals("") || (!bExists)){
            sIDLUrl = "http://api.openoffice.org/" + Inspector.sIDLDOCUMENTSUBFOLDER;
        }
        if (!sIDLUrl.endsWith("/")){
            sIDLUrl += "/";
        }
        if (_sClassName.equals("")){
            sIDLUrl += "com/sun/star/module-ix";
            sAnchor = "";
        }
        else{
            sIDLUrl += _sClassName.replace('.', '/');
        }
        if (sAnchor != null){
            if (!sAnchor.equals("")){
                sIDLUrl += "#" + sAnchor;
            }
        }
        sIDLUrl += ".html";
        URL openHyperlink = getDispatchURL(".uno:OpenHyperlink");
        PropertyValue pv = new PropertyValue();
        pv.Name = "URL";
        pv.Value = sIDLUrl;
        getXDispatcher(openHyperlink).dispatch(openHyperlink, new PropertyValue[] {pv});
    } catch(Exception exception) {
        exception.printStackTrace(System.out);
    }}


    private com.sun.star.util.URL getDispatchURL(String _sURL){
        try {
            Object oTransformer = getXMultiComponentFactory().createInstanceWithContext("com.sun.star.util.URLTransformer", getXComponentContext());
            XURLTransformer xTransformer = (XURLTransformer) UnoRuntime.queryInterface(XURLTransformer.class, oTransformer);
            com.sun.star.util.URL[] oURL = new com.sun.star.util.URL[1];
            oURL[0] = new com.sun.star.util.URL();
            oURL[0].Complete = _sURL;
            xTransformer.parseStrict(oURL);
        return oURL[0];
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
        return null;
    }


    private XFrame getCurrentFrame(){
    try{
        Object oDesktop = getXMultiComponentFactory().createInstanceWithContext("com.sun.star.frame.Desktop", getXComponentContext());
        XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, oDesktop);
        return xDesktop.getCurrentFrame();
    } catch (Exception e) {
        e.printStackTrace(System.out);
        return null;
    }}


    private XDispatch getXDispatcher(com.sun.star.util.URL oURL) {
    try {
        com.sun.star.util.URL[] oURLArray = new com.sun.star.util.URL[1];
        oURLArray[0] = oURL;
        XDispatchProvider xDispatchProvider = (XDispatchProvider) UnoRuntime.queryInterface(XDispatchProvider.class, getCurrentFrame());
        XDispatch xDispatch = xDispatchProvider.queryDispatch(oURLArray[0], "_top", FrameSearchFlag.ALL); // "_self"
        return xDispatch;
    } catch (Exception e) {
        e.printStackTrace(System.out);
        return null;
    }}


    private PropertyValue[] loadArgs(String url) {
        PropertyValue pv = new PropertyValue();
        pv.Name = "URL";
        pv.Value = url;
        return new PropertyValue[] {pv};
    }



    public boolean isFilterApplicable(String _sFilter, String _sName){
        boolean bFilterDoesApply = true;
        if (_sFilter.length() > 0){
            if (_sName.indexOf(_sFilter) == -1){
                bFilterDoesApply = false;
            }
        }
        return bFilterDoesApply;
    }


//    public static String getServiceDescription(Object _oUnoObject){
//        String sClassName = "";
//        XServiceInfo xServiceInfo = (XServiceInfo) UnoRuntime.queryInterface(XServiceInfo.class, _oUnoObject);
//        if (xServiceInfo != null){
//            String[] sChildServiceNames = removeMandatoryServiceNames(xServiceInfo.getSupportedServiceNames());
//            if (sChildServiceNames.length > 0){
//                sClassName = sChildServiceNames[0];
//            }
//        }
//        return sClassName;
//    }



    private static String[] getMandatoryServiceNames(String _sServiceName){
    String[] sMandatoryServiceNames  = new String[]{};
    try {
        TypeClass[] eTypeClasses = new com.sun.star.uno.TypeClass[1];
        eTypeClasses[0] = com.sun.star.uno.TypeClass.SERVICE;
        XTypeDescriptionEnumeration xTDEnumeration = getXTypeDescriptionEnumerationAccess().createTypeDescriptionEnumeration(Introspector.getModuleName(_sServiceName), eTypeClasses, TypeDescriptionSearchDepth.INFINITE);
        while (xTDEnumeration.hasMoreElements()) {
            XTypeDescription xTD = xTDEnumeration.nextTypeDescription();
            if (xTD.getName().equals(_sServiceName)){
                XServiceTypeDescription xServiceTypeDescription = (XServiceTypeDescription) UnoRuntime.queryInterface(XServiceTypeDescription.class, xTD);
                XServiceTypeDescription[] xMandatoryServiceTypeDescriptions =  xServiceTypeDescription.getMandatoryServices();
                int nlength = xMandatoryServiceTypeDescriptions.length;
                sMandatoryServiceNames  = new String[nlength];
                for (int i = 0; i < nlength; i++){
                    sMandatoryServiceNames[i] = xMandatoryServiceTypeDescriptions[i].getName();
                }

            }
        }
    } catch ( java.lang.Exception e) {
        System.out.println(System.out);
    }
        return sMandatoryServiceNames;
    }


    private static String[] removeMandatoryServiceNames(String[] _sServiceNames){
    try{
        List aList = java.util.Arrays.asList(_sServiceNames);
        Vector aVector = new Vector(aList);
        for (int n = 0; n < _sServiceNames.length; n++){
            String[] sDelServiceNames = getMandatoryServiceNames(_sServiceNames[n]);
            for (int m = 0; m < sDelServiceNames.length; m++){
                if (aVector.contains(sDelServiceNames[m])){
                    int nIndex = aVector.indexOf(sDelServiceNames[m]);
                    aVector.remove(nIndex);
                }
            }
        }
        String[] sRetArray = new String[aVector.size()];
        aVector.toArray(sRetArray);
        return sRetArray;
    } catch (java.lang.Exception exception) {
        exception.printStackTrace(System.out);
    }
        return new String[]{};
    }


    public  static String getDisplayValueOfPrimitiveType(Object _objectElement){
    String sValue ="";
    try{
        if (AnyConverter.isString(_objectElement)){
            sValue = AnyConverter.toString(_objectElement);
        }
        else if (AnyConverter.isBoolean(_objectElement)){
            sValue += AnyConverter.toBoolean(_objectElement);
        }
        else if (AnyConverter.isByte(_objectElement)){
            sValue += AnyConverter.toByte(_objectElement);
        }
        else if (AnyConverter.isChar(_objectElement)){
            sValue += AnyConverter.toChar(_objectElement);
        }
        else if (AnyConverter.isDouble(_objectElement)){
            sValue += AnyConverter.toDouble(_objectElement);
        }
        else if (AnyConverter.isFloat(_objectElement)){
            sValue += AnyConverter.toFloat(_objectElement);
        }
        else if (AnyConverter.isInt(_objectElement)){
            sValue += AnyConverter.toInt(_objectElement);
        }
        else if (AnyConverter.isLong(_objectElement)){
            sValue += AnyConverter.toLong(_objectElement);
        }
        else if (AnyConverter.isShort(_objectElement)){
            sValue += AnyConverter.toShort(_objectElement);
        }
    }
    catch( Exception e ) {
        System.err.println( e );
    }
        return sValue;
    }

    protected static String[] getDisplayValuesofPrimitiveArray(Object _oUnoObject){
    String[] sDisplayValues = null;
    try{
        Type aType = AnyConverter.getType(_oUnoObject);
        TypeClass aTypeClass = aType.getTypeClass();
        int nTypeValue = aTypeClass.getValue();
        if (nTypeValue == TypeClass.SEQUENCE_value){
            nTypeValue = (sequenceComponentType(aType)).getTypeClass().getValue();
        }
        switch (nTypeValue){
            case TypeClass.BOOLEAN_value:
                boolean[] bBooleans = (boolean[]) AnyConverter.toArray(_oUnoObject);
                sDisplayValues = new String[bBooleans.length];
                for (int i = 0; i < bBooleans.length; i++){
                    sDisplayValues[i] = Boolean.toString(bBooleans[i]);
                }
                break;
            case TypeClass.BYTE_value:
                byte[] bBytes = (byte[]) AnyConverter.toArray(_oUnoObject);
                sDisplayValues = new String[bBytes.length];
                for (int i = 0; i < bBytes.length; i++){
                    sDisplayValues[i] = "" + bBytes[i];
                }
                break;
            case TypeClass.DOUBLE_value:
                double[] fdoubles = (double[]) AnyConverter.toArray(_oUnoObject);
                sDisplayValues = new String[fdoubles.length];
                for (int i = 0; i < fdoubles.length; i++){
                    sDisplayValues[i] = String.valueOf(fdoubles[i]);
                }
                break;
            case TypeClass.FLOAT_value:
                float[] ffloats = (float[]) AnyConverter.toArray(_oUnoObject);
                sDisplayValues = new String[ffloats.length];
                for (int i = 0; i < ffloats.length; i++){
                    sDisplayValues[i] = String.valueOf(ffloats[i]);
                }
                break;
            case TypeClass.LONG_value:
                int[] nints = (int[]) AnyConverter.toArray(_oUnoObject);
                sDisplayValues = new String[nints.length];
                for (int i = 0; i < nints.length; i++){
                    sDisplayValues[i] = String.valueOf(nints[i]);
                }
                break;
            case TypeClass.HYPER_value:
                long[] nlongs = (long[]) AnyConverter.toArray(_oUnoObject);
                sDisplayValues = new String[nlongs.length];
                for (int i = 0; i < nlongs.length; i++){
                    sDisplayValues[i] = String.valueOf(nlongs[i]);
                }
                break;
            case TypeClass.SHORT_value:
                short[] nShorts = (short[]) AnyConverter.toArray(_oUnoObject);
                sDisplayValues = new String[nShorts.length];
                for (int i = 0; i < nShorts.length; i++){
                    sDisplayValues[i] = "" +  nShorts[i];
                }
                break;
            case TypeClass.CHAR_value:
                break;
            default:
                System.out.println("Value could not be retrieved: " + aType.getTypeClass().getClass().getName());
            }
        return sDisplayValues;
    }
    catch( Exception e ) {
        System.err.println( e );
        return null;
    }}


    private static Type sequenceComponentType(Type sequenceType) {
//        assert sequenceType.getTypeClass() == TypeClass.SEQUENCE;
        String n = sequenceType.getTypeName();
        final String PREFIX = "[]";
//        assert n.startsWith(PREFIX);
        return new Type(n.substring(PREFIX.length()));
    }


    public static String getNodeDescription(Object _oUnoObject, int _nIndex){
        return getNodeDescription(_oUnoObject) + "[" + (_nIndex + 1) + "]";
    }


    public static String getNodeDescription(Object _oUnoObject){
        XServiceInfo xServiceInfo = ( XServiceInfo ) UnoRuntime.queryInterface( XServiceInfo.class, _oUnoObject );
        if ( xServiceInfo != null ) {
            return xServiceInfo.getImplementationName();
        }
        String sClassName = _oUnoObject.getClass().getName();
        if (Introspector.getIntrospector().isObjectPrimitive(_oUnoObject)){         //super.isO{sObjectClassName.equals("java.lang.String"))issClassName.equals("java.lang.String"))
            return _oUnoObject.toString();
        }
        else{
            return _oUnoObject.getClass().getName();
        }
    }

    public void setParameterObjects(Object[] _oParamObjects){
        m_oParamObjects = _oParamObjects;
    }

    public Object[] getParameterObjects(){
        return m_oParamObjects;
    }
}
