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



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_i18npool.hxx"

#include <collatorImpl.hxx>
#include <com/sun/star/i18n/CollatorOptions.hpp>
#include <rtl/ustrbuf.hxx>

using namespace com::sun::star;
using namespace com::sun::star::lang;
using namespace com::sun::star::uno;
using namespace rtl;

namespace com { namespace sun { namespace star { namespace i18n {

CollatorImpl::CollatorImpl( const Reference < XMultiServiceFactory >& rxMSF ) : xMSF(rxMSF)
{
    if ( rxMSF.is()) {
        Reference < XInterface > xI =
            xMSF->createInstance( OUString::createFromAscii("com.sun.star.i18n.LocaleData"));
        if ( xI.is() )
            xI->queryInterface(::getCppuType((const Reference< XLocaleData>*)0)) >>= localedata;
    }
    cachedItem = NULL;
}

CollatorImpl::~CollatorImpl()
{
    // Clear lookuptable
    for (size_t l = 0; l < lookupTable.size(); l++)
        delete lookupTable[l];
    lookupTable.clear();
}

sal_Int32 SAL_CALL
CollatorImpl::compareSubstring( const OUString& str1, sal_Int32 off1, sal_Int32 len1,
    const OUString& str2, sal_Int32 off2, sal_Int32 len2) throw(RuntimeException)
{
    if (cachedItem)
        return cachedItem->xC->compareSubstring(str1, off1, len1, str2, off2, len2);

    sal_Unicode *unistr1 = (sal_Unicode*) str1.getStr() + off1;
    sal_Unicode *unistr2 = (sal_Unicode*) str2.getStr() + off2;
    for (int i = 0; i < len1 && i < len2; i++)
        if (unistr1[i] != unistr2[i])
            return unistr1[i] < unistr2[i] ? -1 : 1;
    return len1 == len2 ? 0 : (len1 < len2 ? -1 : 1);
}

sal_Int32 SAL_CALL
CollatorImpl::compareString( const OUString& in_str1, const OUString& in_str2) throw(RuntimeException)
{
    if (cachedItem)
        return cachedItem->xC->compareString(in_str1, in_str2);

    return CollatorImpl::compareSubstring(in_str1, 0, in_str1.getLength(), in_str2, 0, in_str2.getLength());
}


sal_Int32 SAL_CALL
CollatorImpl::loadDefaultCollator(const lang::Locale& rLocale, sal_Int32 collatorOptions) throw(RuntimeException)
{
    const Sequence< Implementation > &imp = localedata->getCollatorImplementations(rLocale);
    for (sal_Int16 i = 0; i < imp.getLength(); i++)
        if (imp[i].isDefault)
            return loadCollatorAlgorithm(imp[i].unoID, rLocale, collatorOptions);

    throw RuntimeException(); // not default is defined
    //return 0;
}

sal_Int32 SAL_CALL
CollatorImpl::loadCollatorAlgorithm(const OUString& impl, const lang::Locale& rLocale, sal_Int32 collatorOptions)
    throw(RuntimeException)
{
    if (! cachedItem || ! cachedItem->equals(rLocale, impl))
        loadCachedCollator(rLocale, impl);

    if (cachedItem)
        cachedItem->xC->loadCollatorAlgorithm(cachedItem->algorithm, nLocale = rLocale, collatorOptions);
    else
        throw RuntimeException(); // impl could not be loaded

    return 0;
}

void SAL_CALL
CollatorImpl::loadCollatorAlgorithmWithEndUserOption(const OUString& impl, const lang::Locale& rLocale,
    const Sequence< sal_Int32 >& collatorOptions) throw(RuntimeException)
{
    sal_Int32 options = 0;
    for (sal_Int32 i = 0; i < collatorOptions.getLength(); i++)
        options |= collatorOptions[i];
    loadCollatorAlgorithm(impl, rLocale, options);
}

Sequence< OUString > SAL_CALL
CollatorImpl::listCollatorAlgorithms( const lang::Locale& rLocale ) throw(RuntimeException)
{
    nLocale = rLocale;
    const Sequence< Implementation > &imp = localedata->getCollatorImplementations(rLocale);
    Sequence< OUString > list(imp.getLength());

    for (sal_Int32 i = 0; i < imp.getLength(); i++) {
        //if the current algorithm is default and the position is not on the first one, then switch
        if (imp[i].isDefault && i) {
            list[i] = list[0];
            list[0] = imp[i].unoID;
        }
        else
            list[i] = imp[i].unoID;
    }
    return list;
}

Sequence< sal_Int32 > SAL_CALL
CollatorImpl::listCollatorOptions( const OUString& /*collatorAlgorithmName*/ ) throw(RuntimeException)
{
    Sequence< OUString > option_str = localedata->getCollationOptions(nLocale);
    Sequence< sal_Int32 > option_int(option_str.getLength());

    for (sal_Int32 i = 0; i < option_str.getLength(); i++)
        option_int[i] =
            option_str[i].equalsAscii("IGNORE_CASE") ?  CollatorOptions::CollatorOptions_IGNORE_CASE :
            option_str[i].equalsAscii("IGNORE_KANA") ?  CollatorOptions::CollatorOptions_IGNORE_KANA :
            option_str[i].equalsAscii("IGNORE_WIDTH") ?  CollatorOptions::CollatorOptions_IGNORE_WIDTH : 0;

    return option_int;
}

sal_Bool SAL_CALL
CollatorImpl::createCollator(const lang::Locale& rLocale, const OUString& serviceName, const OUString& rSortAlgorithm)
    throw(RuntimeException)
{
    for (size_t l = 0; l < lookupTable.size(); l++) {
        cachedItem = lookupTable[l];
        if (cachedItem->service.equals(serviceName)) {// cross locale sharing
            lookupTable.push_back(cachedItem = new lookupTableItem(rLocale, rSortAlgorithm, serviceName, cachedItem->xC));
            return sal_True;
        }
    }
    if (xMSF.is()) {
        Reference < XInterface > xI =
            xMSF->createInstance(OUString::createFromAscii("com.sun.star.i18n.Collator_") + serviceName);

        if (xI.is()) {
            Reference < XCollator > xC;
            xI->queryInterface( getCppuType((const Reference< XCollator>*)0) ) >>= xC;
            if (xC.is()) {
                lookupTable.push_back(cachedItem = new lookupTableItem(rLocale, rSortAlgorithm, serviceName, xC));
                return sal_True;
            }
        }
        return sal_False;
    }
    throw RuntimeException();
}

void SAL_CALL
CollatorImpl::loadCachedCollator(const lang::Locale& rLocale, const OUString& rSortAlgorithm)
    throw(RuntimeException)
{
    for (size_t i = 0; i < lookupTable.size(); i++) {
        cachedItem = lookupTable[i];
        if (cachedItem->equals(rLocale, rSortAlgorithm)) {
            return;
        }
    }

    static sal_Unicode under = (sal_Unicode) '_';
    static OUString tw(OUString::createFromAscii("TW"));
    static OUString unicode(OUString::createFromAscii("Unicode"));

    sal_Int32 l = rLocale.Language.getLength();
    sal_Int32 c = rLocale.Country.getLength();
    sal_Int32 v = rLocale.Variant.getLength();
    sal_Int32 a = rSortAlgorithm.getLength();
    OUStringBuffer aBuf(l+c+v+a+4);

    if ((l > 0 && c > 0 && v > 0 && a > 0 &&
                // load service with name <base>_<lang>_<country>_<varian>_<algorithm>
                createCollator(rLocale, aBuf.append(rLocale.Language).append(under).append(rLocale.Country).append(
                        under).append(rLocale.Variant).append(under).append(rSortAlgorithm).makeStringAndClear(),
                    rSortAlgorithm)) ||
            (l > 0 && c > 0 && a > 0 &&
             // load service with name <base>_<lang>_<country>_<algorithm>
             createCollator(rLocale, aBuf.append(rLocale.Language).append(under).append(rLocale.Country).append(
                     under).append(rSortAlgorithm).makeStringAndClear(), rSortAlgorithm)) ||
            (l > 0 && c > 0 && a > 0 && rLocale.Language.equalsAscii("zh") &&
             (rLocale.Country.equalsAscii("HK") ||
              rLocale.Country.equalsAscii("MO")) &&
             // if the country code is HK or MO, one more step to try TW.
             createCollator(rLocale, aBuf.append(rLocale.Language).append(under).append(tw).append(under).append(
                     rSortAlgorithm).makeStringAndClear(), rSortAlgorithm)) ||
            (l > 0 && a > 0 &&
             // load service with name <base>_<lang>_<algorithm>
             createCollator(rLocale, aBuf.append(rLocale.Language).append(under).append(rSortAlgorithm).makeStringAndClear(),
                 rSortAlgorithm)) ||
            // load service with name <base>_<algorithm>
            (a > 0 &&
             createCollator(rLocale, rSortAlgorithm, rSortAlgorithm)) ||
            // load default service with name <base>_Unicode
            createCollator(rLocale, unicode, rSortAlgorithm)) {
                return;
            } else {
                cachedItem = NULL;
                throw RuntimeException(); // could not load any service
            }
}

const sal_Char cCollator[] = "com.sun.star.i18n.Collator";

OUString SAL_CALL
CollatorImpl::getImplementationName() throw( RuntimeException )
{
    return OUString::createFromAscii(cCollator);
}

sal_Bool SAL_CALL
CollatorImpl::supportsService(const OUString& rServiceName)
                throw( RuntimeException )
{
    return rServiceName.equalsAscii(cCollator);
}

Sequence< OUString > SAL_CALL
CollatorImpl::getSupportedServiceNames() throw( RuntimeException )
{
    Sequence< OUString > aRet(1);
    aRet[0] = OUString::createFromAscii(cCollator);
    return aRet;
}

} } } }
