/*
 *    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 "winreg.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
{
    const IWordBreakerVtbl *lpVtbl;
    LONG ref;
} wordbreaker_impl;

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

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

    *ppvObj = NULL;

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

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

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

static ULONG WINAPI wb_Release(IWordBreaker *iface)
{
    wordbreaker_impl *This = (wordbreaker_impl *)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,
};

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->lpVtbl = &wordbreaker_vtbl;

    wb = (IWordBreaker*) This;

    return IWordBreaker_QueryInterface(wb, riid, ppvObject);
}
