/*
**  CEView+TextUtils.m
**
**  Copyright (c) 2002, 2003
**
**  Author: Yen-Ju Chen <yjchenx@hotmail.com>
**          Bjoern Giesler <bjoern@giesler.de>
**
**  This program is free software; you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation; either version 2 of the License, or
**  (at your option) any later version.
**
**  This program 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 General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "CEView+TextUtils.h"
#include <AppKit/AppKit.h>

@implementation CodeEditorView (TextUtils)

#define CURSOR ([self selectedRange].location)

/* The relationship of position and cString are:
 *
 * cString     0     1     2     3
 *             A     B     C     D
 * position       0     1     2     3
 *
 * position is selectedRange.location+selectedLength
 */

- (NSString *) wordAtPosition: (int) position
                      inRange: (NSRange *) theRange
                  searchRange: (NSRange) searchRange
{
  char *str; 
  int len, start, end;
  NSRange range;

  /* Trim the range */
  len = [[self string] length];

  if (searchRange.location < 0)
    {
      searchRange.length = searchRange.length+searchRange.location;
      searchRange.location = 0;
    }
  if (searchRange.location+searchRange.length > len)
    {
      searchRange.length = len - searchRange.location;
    }

  if ((searchRange.location == 0) && (searchRange.length == [[self string] length]))
    { /* Search whole string */
      str = (char *)[[self string] lossyCString];
      len = strlen(str);
    }
  else
    {
      str = (char*) [[[self string] substringFromRange: searchRange] lossyCString];
      len = strlen(str);
      position = position - searchRange.location;
    }

  if(position < 0)
    range = NSMakeRange(0, 0);
  else if(!isalnum(str[position]))
    range = NSMakeRange(position, position == len ? 0 : 1);
  else if(!isspace(str[position]))
    {
      for(start = position; start > 0 && isalnum(str[start-1]); start--);
      for(end = position; end < len && isalnum(str[end]); end++);
      range = NSMakeRange(start, end - start);
    }
  else
    range = NSMakeRange(position, 0);

  if (range.length == 0)
    range.location = NSNotFound;
  if (theRange)
    {
      range.location += searchRange.location;
      (*theRange) = range;
    }

  if (range.length == 0) // Not Found
    return nil;
  else
    return [[self string] substringWithRange: range];
}

- (NSString *)lineAtPosition: (int) position
                     inRange: (NSRange *) theRange
                 searchRange: (NSRange) searchRange
{
  char *str; 
  int len, start, end;
  NSRange range;
  
  str = (char *)[[self string] lossyCString];
  len = strlen(str);

  for(start = position - 1; start >= 0 && str[start]!='\n'; start--);
  start++;
  for(end = position; end < len && str[end] != '\n'; end++);
  if(end - start < 0)
    range = NSMakeRange(start, 0);
  else if(end < len)
    range = NSMakeRange(start, end-start+1);
  else
    range = NSMakeRange(start, end-start);

  if (range.length == 0)
    range.location = position;

  if(theRange)
    (*theRange)=range;

  if(range.location == NSNotFound)
	return @"";
  else
	return [[self string] substringWithRange: range];
}

- (NSString *) wordAtPosition: (int) position
                      inRange: (NSRange *) range
{
  return [self wordAtPosition: position
                      inRange: range
                  searchRange: NSMakeRange(0, [[self string] length])];
}

- (NSString *) lineAtPosition: (int) position
                      inRange: (NSRange *) range
{
  return [self lineAtPosition: position
                      inRange: range
                  searchRange: NSMakeRange(0, [[self string] length])];
}

- (NSRange)rangeOfWordAtPosition: (int) position
{
  NSRange range;
  [self wordAtPosition: position inRange: &range];
  return range;
}

- (NSRange)rangeOfWordAtCursor
{
  return [self rangeOfWordAtPosition: CURSOR-1];
}

- (NSString *)wordAtPosition: (int) position
{
  return [self wordAtPosition: position inRange: NULL];
}

- (NSString *)wordAtCursor
{
  return [self wordAtPosition: CURSOR-1 inRange: NULL];
}

- (NSRange)rangeOfLineAtPosition: (int)position
{
  NSRange range;
  [self lineAtPosition: position inRange: &range];
  return range;
}
- (NSRange)rangeOfLineAtCursor
{
  return [self rangeOfLineAtPosition: CURSOR-1];
}
- (NSString *)lineAtPosition: (int)position
{
  return [self lineAtPosition: position inRange: NULL];
}
- (NSString *)lineAtCursor
{
  return [self lineAtPosition: CURSOR-1 inRange: NULL];
}

/* Return the line number at position. Begin from 1 */
- (unsigned) lineNumberAtPosition: (int) position
{
  char *str;
  int len, i;
  unsigned atl=1;
  
  str = (char *)[[self string] lossyCString];
  len = strlen(str);
  
  if (position > len)
    position = len;
  
  for (i=0; i<=position; i++)
    {
      if(str[i] == '\n')
        atl++;
    }
  return atl;
}

@end
