//
//  LineReader.m
//  MHP3SkillSim
//
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "LineReader.h"
#import <stdio.h>
#import <stdlib.h>
#import <fcntl.h>
#import <sys/stat.h>
#import "PSMutex.h"
#import "SkillSet.h"

@implementation LineReader

#define BUFFER_SIZE (1024*1024*10)

@synthesize columns = _columns;
@synthesize currentRow = _currentRow;
@synthesize currentLine = _currentLine;
@synthesize lines = _lines;

-(id)init {
    self = [super init];
    if (self) {
        _columns = nil;
        _lines = nil;
    }else {
        [[PSMutex mainMutex] raiseMemoryError];
    }
    [[PSMutex mainMutex] showMemoryAlertIfError];
    return self;
}

-(void)dealloc
{
    if (_lines != nil) {
        [_lines release];
        _lines = nil;
    }
   if (_columns != nil) {
        [_columns release];
        _columns = nil;
    }
    [super dealloc];
}

#define USER_SETTING 1

- (BOOL) readFile : (NSString*) fileName {
	NSFileManager *fileManager = [NSFileManager defaultManager];
	NSString *filePath = [NSString stringWithFormat:@"%@/Documents/%@" , NSHomeDirectory(), fileName];
    
    if (filePath == nil) {
        NSException *exception = [[NSException alloc]initWithName:@"memoryerror" reason:@"nil" userInfo:nil];
        [exception raise];
    }
    
	if(USER_SETTING && [fileManager fileExistsAtPath:filePath]) {
        //NSLog(@"open file %@", filePath);
    }else {
        NSBundle* bundle = [NSBundle mainBundle];
        //[filePath release];
        NSString* filePath2 = [bundle pathForResource: fileName ofType:nil];
        if (filePath2 == nil) {
            //NSLog(@"no file for %@", fileName);
            return FALSE;
        }
        filePath = filePath2;
        //NSLog(@"open file %@", filePath);
    }
    
    NSURL* url = [NSURL fileURLWithPath:filePath];
    NSError* error = [[NSError alloc]init];
    NSString* str = [NSString stringWithContentsOfURL:url encoding:NSShiftJISStringEncoding error: &error];
    
    BOOL ret = [self readFromString:str];
    //[str release];

    return ret;
}

- (BOOL) readPasteBoard {
    NSString* str = [UIPasteboard generalPasteboard].string;
    if (str != nil) {
        return [self readFromString:str];
    }
    return FALSE;
}

-(BOOL)readFromString:(NSString *)strContents {
    [_lines release];
    _lines = [[NSMutableArray alloc]init];
    if (strContents != nil) {
        [LineReader splitPerLines:strContents :_lines];
    }
    _currentRow = 0;
    
    return TRUE;
}

+ (BOOL) splitPerColumns: (NSString*)text : (NSMutableArray*)columns {
    int startIndex = 0;
    NSRange range;
    while(1) {
        int found = -1;
        for(int x = startIndex; x < text.length; ++ x) {
            int ch = [text characterAtIndex: x];
            if(ch == ',' || ch == 0 || ch == '\n' || ch == '\r') {
                found = x;
                break;
            }
        }
        if (found < 0) {
            if (startIndex < text.length) {
                range.location = startIndex;
                range.length = text.length - startIndex;
                
                while (range.length >= 1 && [text hasPrefix: @" "]) {
                    range.location ++;
                    range.length --;
                }
                while (range.length >= 1 && [text hasSuffix: @" "]) {
                    range.length --;
                }
                while (range.length >= 2 && [text characterAtIndex:0] == '"') {
                    int suffix = [text characterAtIndex: range.location + range.length -1];
                    if (suffix == '"') {
                        range.location ++;
                        range.length -= 2;
                    }else {
                        break;
                    }
                }
                NSString* str = [text substringWithRange:range];
                [columns addObject:str];
            }
            break;
        }
        range.location = startIndex;
        range.length = found - startIndex;
        while (range.length >= 1 && [text hasPrefix: @" "]) {
            range.location ++;
            range.length --;
        }
        while (range.length >= 1 && [text hasSuffix: @" "]) {
            range.length --;
        }
        while (range.length >= 2 && [text characterAtIndex:range.location] == '"') {
            int suffix = [text characterAtIndex: range.location + range.length -1];
            if (suffix == '"') {
                range.location ++;
                range.length -= 2;
            }else {
                break;
            }
        }
        NSString* str = [text substringWithRange:range];
        [columns addObject:str];
        startIndex = found + 1;
    }
    return TRUE;
}

+ (BOOL) splitPerLines: (NSString*)text : (NSMutableArray*)lines {
    int startIndex = 0;
    NSRange range;

    while(1) {
        int found = -1;
        for(int x = startIndex; x < text.length; ++ x) {
            int ch = [text characterAtIndex: x];
            if(ch == 0 || ch == '\n' || ch == '\r') {
                found = x;
                break;
            }
        }
        if (found < 0) {
            if (startIndex < text.length) {
                range.location = startIndex;
                range.length = text.length - startIndex;
                
                while (range.length >= 1 && [text hasPrefix: @" "]) {
                    range.location ++;
                    range.length --;
                }
                while (range.length >= 1 && [text hasSuffix: @" "]) {
                    range.length --;
                }
                while (range.length >= 2 && [text characterAtIndex:0] == '"') {
                    int suffix = [text characterAtIndex: range.location + range.length -1];
                    if (suffix == '"') {
                        range.location ++;
                        range.length -= 2;
                    }else {
                        break;
                    }
                }
                NSString* str = [text substringWithRange:range];
                [lines addObject:str];
            }
            break;
        }
        range.location = startIndex;
        range.length = found - startIndex;
        while (range.length >= 1) {
            int ch = [text characterAtIndex: range.location];
            if (ch == ' ' || ch ==  '\r' || ch == '\n') {
                range.location ++;
                range.length --;
                continue;
            }
            break;
        }
        while (range.length >= 1) {
            int ch = [text characterAtIndex: range.location + range.length -1];
            if (ch == ' ' || ch ==  '\r' || ch == '\n') {
                range.length --;
                continue;
            }
            break;
        }
        NSString* str = [text substringWithRange:range];
        [lines addObject:str];
        startIndex = found + 1;
    }
    return TRUE;
}

- (BOOL) parseNextLine 
{
    while (true) {
        if (_currentRow < _lines.count) {
            _currentLine = [_lines objectAtIndex: _currentRow];
            [_columns release];
            _columns = [[NSMutableArray alloc]init]; 
            [LineReader splitPerColumns:_currentLine :_columns];
            
            _currentRow ++;
            
            if (_currentLine.length == 0) {
                continue;
            }
            if ([_currentLine characterAtIndex:0] == '#') {
                continue;
            }
            return TRUE;
        }else {
            return FALSE;
        }
    }
}

- (int) columnCount
{
    if (_columns != nil) {
        return _columns.count;
    }
    return -1;
}

- (NSString*) columnAtIndex:(int)index
{
    if (_columns != nil) {
        return [_columns objectAtIndex: index];
    }
    return nil;
}

+(void)renketu: (NSMutableString*) str: (NSArray*) array {
    BOOL first = TRUE;
    for (int i = 0; i < array.count; ++ i) {
        if (first) {
            first = FALSE;
        }else {
            [str appendString:@","];
        }
        NSString* elem = [array objectAtIndex:i];
        NSRange range = [elem rangeOfString:@","];
        if (range.length > 0) {
            [str appendFormat:@"\"%@\"", elem];
        }else {
            [str appendString:elem];
        }
    }
}

+(BOOL)StringToSkillSet:(NSString*)text : (SkillSet*)skills {
    [skills cleanup];
    NSMutableArray* columns = [[NSMutableArray alloc]init];
    
    [LineReader splitPerColumns: text: columns];
    
    for (int i = 0; i < columns.count; ++ i) {
        NSString* value = [columns objectAtIndex:i];
        
        NSRange range =  [value rangeOfString: @"="];
        if (range.length <= 0) {
            continue;
        }
        NSString* kind = [value substringToIndex:range.location];
        value = [value substringFromIndex:range.location + 1];
        
        BOOL positiveRange = TRUE;
        if ([value hasSuffix: @"+"]) {
            positiveRange = TRUE;
            value = [value substringToIndex: value.length - 1];
        }else if ([value hasSuffix: @"-"]) {
            positiveRange = FALSE;
            value = [value substringToIndex: value.length - 1];
        }
        
        SkillKind *kindObj = [SkillKind findKindByName: kind];
        if (kindObj == nil) {
            NSLog(@"error on find kind about %@", kind); 
            continue;
        }
        
        [skills set:kindObj :value.intValue :positiveRange];
    }
    return TRUE;
}

+(BOOL)SkillSetToString:(SkillSet*)skills : (NSMutableString*)text {
    NSMutableArray* array = [[NSMutableArray alloc]init];
    for (int i = 0; i < skills.count; ++ i) {
        NSMutableString* str = [[NSMutableString alloc]init];
        SkillKind* kind = [skills.listKind objectAtIndex:i];
        int point = skills.point[i];
        BOOL positive = skills.positive[i];
        
        if (point == 0) {
            continue;
        }
        [str appendFormat:@"%@=%d%@", kind.name, point, positive ? @"+" : @"-"];
        
        [array addObject:str];
        [str release];
    }
    [LineReader renketu: text :array];
    return TRUE;
}

@end
