/*
 * RichEdit - Operations on rows of text (rows are recreated during
 * wrapping and are used for displaying the document, they don't keep any
 * true document content; delete all rows, rewrap all paragraphs and 
 * you get them back).
 * 
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */ 


#include "editor.h"

ME_DisplayItem *ME_FindRowStart(ME_Context *c, ME_DisplayItem *item, 
                                int nRelPos) {
  ME_DisplayItem *para = ME_GetParagraph(item);
  ME_MustBeWrapped(c, para);
  if(nRelPos>=0) { /* if this or preceding row */
    while(nRelPos<=0) {
      ME_DisplayItem *item2 = ME_FindItemBack(item, diStartRowOrParagraph);
      if (item2->type == diParagraph)
      {
        if (item2->member.para.prev_para == NULL)
          return item;
        /* if skipping to the preceding paragraph, ensure it's wrapped */
        ME_MustBeWrapped(c, item2->member.para.prev_para);
        item = item2;
        continue;
      }
      else if (item2->type == diStartRow)
      {
        nRelPos++;
        if (nRelPos>0)
          return item;
        item = item2;
        continue;
      }
      assert(0 == "bug in FindItemBack(item, diStartRowOrParagraph)");
      item = item2;
    }
    return item;
  }
  while(nRelPos>0) { /* if one of the next rows */
    ME_DisplayItem *item2 = ME_FindItemFwd(item, diStartRowOrParagraph);
    if (!item2)
      return item;
    if (item2->type == diParagraph)
    {
      if (item2->member.para.next_para == NULL)
        return item;
      continue;
    }
    item = item2;
    nRelPos--;
  }
  return item;
}

/* I'm sure these functions would simplify some code in caret ops etc,
 * I just didn't remember them when I wrote that code
 */ 

ME_DisplayItem *ME_RowStart(ME_DisplayItem *item) {
  return ME_FindItemBackOrHere(item, diStartRow);
}

/*
ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item) {
  ME_DisplayItem *item2 = ME_FindItemFwd(item, diStartRowOrParagraphOrEnd);
  if (!item2) return NULL;
  return ME_FindItemBack(item, diRun);
}
*/

ME_DisplayItem *
ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
{
  ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
  int nCount = 0;
  
  while (item && nCount + item->member.para.nRows <= nRow)
  {
    nCount += item->member.para.nRows;
    item = ME_FindItemFwd(item, diParagraph);
  }
  if (!item)
    return item;
  for (item = ME_FindItemFwd(item, diStartRow); item && nCount < nRow; nCount++)
    item = ME_FindItemFwd(item, diStartRow);
  return item;
}


int
ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs)
{
  ME_DisplayItem *item = editor->pBuffer->pFirst->next;
  int nRow = 0;

  while (item && item->member.para.next_para->member.para.nCharOfs <= nOfs)
  {
    nRow += item->member.para.nRows;
    item = ME_FindItemFwd(item, diParagraph);
  }
  if (item)
  {
    ME_DisplayItem *next_para = item->member.para.next_para;
    
    nOfs -= item->member.para.nCharOfs;
    item = ME_FindItemFwd(item, diRun);
    while ((item = ME_FindItemFwd(item, diStartRowOrParagraph)) != NULL)
    {
      if (item == next_para)
        break;
      item = ME_FindItemFwd(item, diRun);
      if (item->member.run.nCharOfs > nOfs)
        break;
      nRow++;
    }
  }
  return nRow;
}
