/**************************************************************
 * 
 * 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;
    }        
}
