/*
 * RichEdit - string operations
 *
 * Copyright 2004 by Krzysztof Foltman
 *
 * 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
 */

#include "editor.h"     

WINE_DEFAULT_DEBUG_CHANNEL(richedit);

int ME_GetOptimalBuffer(int nLen)
{
  return ((2*nLen+1)+128)&~63;
}

ME_String *ME_MakeString(LPCWSTR szText)
{
  ME_String *s = ALLOC_OBJ(ME_String);
  s->nLen = lstrlenW(szText);
  s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
  s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
  lstrcpyW(s->szData, szText);
  return s;
}

ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars)
{
  ME_String *s = ALLOC_OBJ(ME_String);
  
  s->nLen = nMaxChars;
  s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
  s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
  /* Native allows NUL chars */
  memmove(s->szData, szText, s->nLen * sizeof(WCHAR));
  s->szData[s->nLen] = 0;
  return s;
}

ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars)
{ /* Make a string by repeating a char nMaxChars times */
  int i;
   ME_String *s = ALLOC_OBJ(ME_String);
  
  s->nLen = nMaxChars;
  s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
  s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);

  for (i = 0;i<nMaxChars;i++)
    s->szData[i] = cRepeat;
  s->szData[s->nLen] = 0;
  return s;
}

ME_String *ME_MakeStringB(int nMaxChars)
{ /* Create a buffer (uninitialized string) of size nMaxChars */
  ME_String *s = ALLOC_OBJ(ME_String);
  
  s->nLen = nMaxChars;
  s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
  s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
  s->szData[s->nLen] = 0;
  return s;
}

ME_String *ME_StrDup(ME_String *s)
{
  return ME_MakeStringN(s->szData, s->nLen);
}

void ME_DestroyString(ME_String *s)
{
  FREE_OBJ(s->szData);
  FREE_OBJ(s);
}

void ME_AppendString(ME_String *s1, ME_String *s2)
{
  if (s1->nLen+s2->nLen+1 <= s1->nBuffer) {
    lstrcpyW(s1->szData+s1->nLen, s2->szData);
    s1->nLen += s2->nLen;
  }
  else
  {
    WCHAR *buf;
    s1->nBuffer = ME_GetOptimalBuffer(s1->nLen+s2->nLen+1);

    buf = ALLOC_N_OBJ(WCHAR, s1->nBuffer); 
    lstrcpyW(buf, s1->szData);
    lstrcpyW(buf+s1->nLen, s2->szData);
    FREE_OBJ(s1->szData);
    s1->szData = buf;
    s1->nLen += s2->nLen;
  }
}

ME_String *ME_ConcatString(ME_String *s1, ME_String *s2)
{
  ME_String *s = ALLOC_OBJ(ME_String);
  s->nLen = s1->nLen+s2->nLen;
  s->nBuffer = ME_GetOptimalBuffer(s1->nLen+s2->nLen+1);
  s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
  lstrcpyW(s->szData, s1->szData);
  lstrcpyW(s->szData+s1->nLen, s2->szData);
  return s;  
}

ME_String *ME_VSplitString(ME_String *orig, int charidx)
{
  ME_String *s;

  /*if (charidx<0) charidx = 0;
  if (charidx>orig->nLen) charidx = orig->nLen;
  */
  assert(charidx>=0);
  assert(charidx<=orig->nLen);

  s = ME_MakeString(orig->szData+charidx);
  orig->nLen = charidx;
  orig->szData[charidx] = L'\0';
  return s;
}

int ME_IsWhitespaces(ME_String *s)
{
  /* FIXME multibyte */
  WCHAR *pos = s->szData;
  while(ME_IsWSpace(*pos++))
    ;
  pos--;
  if (*pos)
    return 0;
  else
    return 1;
}

int ME_IsSplitable(ME_String *s)
{
  WCHAR *pos = s->szData;
  WCHAR ch;
  while(ME_IsWSpace(*pos++))
    ;
  pos--;
  while((ch = *pos++) != 0)
  {
    if (ME_IsWSpace(ch))
      return 1;
  }
  return 0;
}

/* FIXME multibyte */
/*
int ME_CalcSkipChars(ME_String *s)
{
  int cnt = 0;
  while(cnt < s->nLen && s->szData[s->nLen-1-cnt]==' ')
    cnt++;
  return cnt;
}
*/

int ME_StrLen(ME_String *s) { 
  return s->nLen;
}

int ME_StrVLen(ME_String *s) {
  return s->nLen;
}

int ME_StrRelPos(ME_String *s, int nVChar, int *pRelChars)
{
  int nRelChars = *pRelChars;
  
  TRACE("%s,%d,&%d\n", debugstr_w(s->szData), nVChar, *pRelChars);

  assert(*pRelChars);
  if (!nRelChars)
    return nVChar;
  
  if (nRelChars>0)
    nRelChars = min(*pRelChars, s->nLen - nVChar);
  else
    nRelChars = max(*pRelChars, -nVChar);
  nVChar += nRelChars;
  *pRelChars -= nRelChars;
  return nVChar;
}

int ME_StrRelPos2(ME_String *s, int nVChar, int nRelChars)
{
  return ME_StrRelPos(s, nVChar, &nRelChars);
}

int ME_VPosToPos(ME_String *s, int nVPos)
{
  return nVPos;
  /*
  int i = 0, len = 0;
  if (!nVPos)
    return 0;
  while (i < s->nLen)
  {
    if (i == nVPos)
      return len;
    if (s->szData[i]=='\\') i++;
    i++;
    len++;
  }
  return len;
  */
}

int ME_PosToVPos(ME_String *s, int nPos)
{
  if (!nPos)
    return 0;
  return ME_StrRelPos2(s, 0, nPos);
}

void ME_StrDeleteV(ME_String *s, int nVChar, int nChars)
{
  int end_ofs;
  
  assert(nVChar >=0 && nVChar <= s->nLen);
  assert(nChars >= 0);
  assert(nVChar+nChars <= s->nLen);
  
  end_ofs = ME_StrRelPos2(s, nVChar, nChars);
  assert(end_ofs <= s->nLen);
  memmove(s->szData+nVChar, s->szData+end_ofs, 2*(s->nLen+1-end_ofs));
  s->nLen -= (end_ofs - nVChar);
}

int ME_GetCharFwd(ME_String *s, int nPos)
{
  int nVPos = 0;
  
  assert(nPos < ME_StrLen(s));
  if (nPos)
    nVPos = ME_StrRelPos2(s, nVPos, nPos);
  
  if (nVPos < s->nLen)
    return s->szData[nVPos];
  return -1;
}

int ME_GetCharBack(ME_String *s, int nPos)
{
  int nVPos = ME_StrVLen(s);
  
  assert(nPos < ME_StrLen(s));
  if (nPos)
    nVPos = ME_StrRelPos2(s, nVPos, -nPos);
  
  if (nVPos < s->nLen)
    return s->szData[nVPos];
  return -1;
}

int ME_FindNonWhitespaceV(ME_String *s, int nVChar) {
  int i;
  for (i = nVChar; i<s->nLen && ME_IsWSpace(s->szData[i]); i++)
    ;
    
  return i;
}

/* note: returns offset of the first trailing whitespace */
int ME_ReverseFindNonWhitespaceV(ME_String *s, int nVChar) {
  int i;
  for (i = nVChar; i>0 && ME_IsWSpace(s->szData[i-1]); i--)
    ;
    
  return i;
}

/* note: returns offset of the first trailing nonwhitespace */
int ME_ReverseFindWhitespaceV(ME_String *s, int nVChar) {
  int i;
  for (i = nVChar; i>0 && !ME_IsWSpace(s->szData[i-1]); i--)
    ;
    
  return i;
}


static int
ME_WordBreakProc(LPWSTR s, INT start, INT len, INT code)
{
  /* FIXME: Native also knows about punctuation */
  TRACE("s==%s, start==%d, len==%d, code==%d\n",
        debugstr_wn(s, len), start, len, code);
  switch (code)
  {
    case WB_ISDELIMITER:
      return ME_IsWSpace(s[start]);
    case WB_LEFT:
    case WB_MOVEWORDLEFT:
      while (start && ME_IsWSpace(s[start - 1]))
        start--;
      while (start && !ME_IsWSpace(s[start - 1]))
        start--;
      return start;
    case WB_RIGHT:
    case WB_MOVEWORDRIGHT:
      if (start && ME_IsWSpace(s[start - 1]))
      {
        while (start < len && ME_IsWSpace(s[start]))
          start++;
      }
      else
      {
        while (start < len && !ME_IsWSpace(s[start]))
          start++;
        while (start < len && ME_IsWSpace(s[start]))
          start++;
      }
      return start;
  }
  return 0;
}


int
ME_CallWordBreakProc(ME_TextEditor *editor, ME_String *str, INT start, INT code)
{
  /* FIXME: ANSIfy the string when bEmulateVersion10 is TRUE */
  if (!editor->pfnWordBreak)
    return ME_WordBreakProc(str->szData, start, str->nLen, code);
  else
    return editor->pfnWordBreak(str->szData, start, str->nLen, code);
}

LPWSTR ME_ToUnicode(BOOL unicode, LPVOID psz)
{
  assert(psz != NULL);

  if (unicode)
    return (LPWSTR)psz;
  else {
    WCHAR *tmp;
    int nChars = MultiByteToWideChar(CP_ACP, 0, (char *)psz, -1, NULL, 0);
    if((tmp = ALLOC_N_OBJ(WCHAR, nChars)) != NULL)
      MultiByteToWideChar(CP_ACP, 0, (char *)psz, -1, tmp, nChars);
    return tmp;
  }
}

void ME_EndToUnicode(BOOL unicode, LPVOID psz)
{
  if (!unicode)
    FREE_OBJ(psz);
}
