/*
 *    Word splitter Implementation
 *
 * Copyright 2006 Mike McCormack
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "indexsrv.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(infosoft);

typedef struct tag_wordbreaker_impl
{
    IWordBreaker IWordBreaker_iface;
    LONG ref;
} wordbreaker_impl;

static inline wordbreaker_impl *impl_from_IWordBreaker(IWordBreaker *iface)
{
    return CONTAINING_RECORD(iface, wordbreaker_impl, IWordBreaker_iface);
}

static HRESULT WINAPI wb_QueryInterface( IWordBreaker *iface,
        REFIID riid, LPVOID *ppvObj)
{
    wordbreaker_impl *This = impl_from_IWordBreaker(iface);

    TRACE("(%p)->(%s)\n",This,debugstr_guid(riid));

    *ppvObj = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IWordBreaker))
    {
        *ppvObj = &This->IWordBreaker_iface;
        return S_OK;
    }

    TRACE("-- E_NOINTERFACE\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI wb_AddRef( IWordBreaker *iface )
{
    wordbreaker_impl *This = impl_from_IWordBreaker(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI wb_Release(IWordBreaker *iface)
{
    wordbreaker_impl *This = impl_from_IWordBreaker(iface);
    LONG refcount;

    refcount = InterlockedDecrement(&This->ref);
    if (!refcount)
        HeapFree(GetProcessHeap(), 0, This);

    return refcount;
}

static HRESULT WINAPI wb_Init( IWordBreaker *iface,
        BOOL fQuery, ULONG ulMaxTokenSize, BOOL *pfLicense )
{
    TRACE("%d %u\n", fQuery, ulMaxTokenSize);
    *pfLicense = FALSE;
    return S_OK;
}

static HRESULT call_sink( IWordSink *pWordSink, TEXT_SOURCE *ts, UINT len )
{
    HRESULT r;

    if (!len)
        return S_OK;

    TRACE("%d %s\n", len, debugstr_w(&ts->awcBuffer[ts->iCur]));

    r = IWordSink_PutWord( pWordSink, len, &ts->awcBuffer[ts->iCur], len, ts->iCur );
    ts->iCur += len;

    return r;
}

static HRESULT WINAPI wb_BreakText( IWordBreaker *iface,
         TEXT_SOURCE *ts, IWordSink *pWordSink, IPhraseSink *pPhraseSink)
{
    UINT len, state = 0;
    WCHAR ch;

    TRACE("%p %p %p\n", ts, pWordSink, pPhraseSink);

    if (pPhraseSink)
        FIXME("IPhraseSink won't be called\n");

    do
    {
        len = 0;
        while ((ts->iCur + len) < ts->iEnd)
        {
            ch = ts->awcBuffer[ts->iCur + len];

            switch (state)
            {
            case 0: /* skip spaces and punctuation */

                if (!ch || ispunctW(ch) || isspaceW(ch))
                    ts->iCur ++;
                else
                    state = 1;
                break;

            case 1: /* find the end of the word */

                if (ch && !ispunctW(ch) && !isspaceW(ch))
                    len++;
                else
                {
                    call_sink( pWordSink, ts, len );
                    len = 0;
                    state = 0;
                }
                break;

            }
        }
        call_sink( pWordSink, ts, len );

    } while (S_OK == ts->pfnFillTextBuffer( ts ));

    return S_OK;
}

static HRESULT WINAPI wb_ComposePhrase( IWordBreaker *iface,
         const WCHAR *pwcNoun, ULONG cwcNoun,
         const WCHAR *pwcModifier, ULONG cwcModifier,
         ULONG ulAttachmentType, WCHAR *pwcPhrase, ULONG *pcwcPhrase)
{
    FIXME("%p %u %p %u %u %p %p\n", pwcNoun, cwcNoun,
          pwcModifier, cwcModifier, ulAttachmentType, pwcPhrase, pcwcPhrase);
    return S_OK;
}

static HRESULT WINAPI wb_GetLicenseToUse( IWordBreaker *iface, const WCHAR **ppwcsLicense )
{
    FIXME("%p\n", ppwcsLicense);
    *ppwcsLicense = NULL;
    return S_OK;
}

static const IWordBreakerVtbl wordbreaker_vtbl =
{
    wb_QueryInterface,
    wb_AddRef,
    wb_Release,
    wb_Init,
    wb_BreakText,
    wb_ComposePhrase,
    wb_GetLicenseToUse,
};

DECLSPEC_HIDDEN HRESULT WINAPI wb_Constructor(IUnknown* pUnkOuter, REFIID riid, LPVOID *ppvObject)
{
    wordbreaker_impl *This;
    IWordBreaker *wb;

    TRACE("%p %s %p\n", pUnkOuter, debugstr_guid(riid), ppvObject);

    This = HeapAlloc(GetProcessHeap(), 0, sizeof *This);
    if (!This)
        return E_OUTOFMEMORY;

    This->ref = 1;
    This->IWordBreaker_iface.lpVtbl = &wordbreaker_vtbl;

    wb = &This->IWordBreaker_iface;

    return IWordBreaker_QueryInterface(wb, riid, ppvObject);
}
