//
//  MHP3DataReader.m
//  MHP3SkillSim
//

#import "MHP3DataIO.h"
#import "Repository.h"
#import "PSItem.h"
#import "PSBaseItems.h"
#import "SkillDB.h"
#import "StringHolder.h"

@implementation MHP3DataIO

-(void) readAll
{
    [ self readSkills: @"MH3SKILL.csv" ];
    [ self readSkillCategory: @"CATEGORY.txt" ];
    [ self readSkillFukugo: @"FUKUGO.txt" ];
    
    Repository* repo = [Repository mainRepository];
    PSBaseItems *itemDB = repo.items;
    
    itemDB.listEquipHead = [ self readEquipmentSub: @"MH3EQUIP_HEAD.csv" : ITEM_TYPE_HEAD  ];
    itemDB.listEquipBody = [ self readEquipmentSub: @"MH3EQUIP_BODY.csv" : ITEM_TYPE_BODY  ];
    itemDB.listEquipArm =  [ self readEquipmentSub: @"MH3EQUIP_ARM.csv"  : ITEM_TYPE_ARM   ];
    itemDB.listEquipWeist = [ self readEquipmentSub: @"MH3EQUIP_WST.csv"  : ITEM_TYPE_WEIST ];
    itemDB.listEquipLeg  = [ self readEquipmentSub: @"MH3EQUIP_LEG.csv"  : ITEM_TYPE_LEG   ];
    itemDB.listDecoration = [ self readDecorationCSV: @"MH3DECO.csv": ITEM_TYPE_DECORATION  ];

    [repo.config readProperties];
}

-(void) readSkills : (NSString*)fileName
{
    Repository* repository = [Repository mainRepository];
    SkillDB* skillDB = repository.skillDB;

    LineReader* reader = [[LineReader alloc]init];
    if ([ reader readFile: fileName ]) {
        @try {
            while ([reader parseNextLine]) {
                if ([reader columnCount] >= 3) {
                    NSString* skillName = [reader columnAtIndex: 0];
                    NSString* kindName  = [reader columnAtIndex: 1];
                    int       point     = [[reader columnAtIndex: 2] integerValue];
                    
                    //kindName = [reader intern:kindName];

                    [ skillDB addSkillName: skillName : kindName : point : point>0 ? YES : NO ];
                }
            }
        }
        @catch (NSException *exception) {
            NSLog(@"exception %@ %@", exception, [exception callStackSymbols]);
       }
        @finally {
            [ reader release ];
        }
    }
}

-(void) readSkillCategory : (NSString*)fileName
{
    Repository* repository = [Repository mainRepository];
    SkillDB* skillDB = repository.skillDB;

    LineReader* reader = [[LineReader alloc]init];
    if ([ reader readFile: fileName ]) {
        @try {
            while ([reader parseNextLine]) {
                if ([reader columnCount] >= 2) {
                    NSString* categoryName = [reader columnAtIndex: 0];
                    for (int i = 1; i < [reader columnCount]; ++ i) {
                        NSString* skillName  = [reader columnAtIndex: i];

                        [skillDB setCategory: categoryName : skillName];
                    }
                }
            }

        }
        @catch (NSException *exception) {
            NSLog(@"exception %@ %@", exception, [exception callStackSymbols]);
        }
        @finally {
            [ reader release ];
        }
    }
    [ skillDB sort ];
}

-(NSMutableArray*) readEquipmentSub : (NSString*)fileName  : (int)itemType
{
    NSMutableArray* list = [[NSMutableArray alloc]init];
    LineReader* reader = [[LineReader alloc]init];
    if ([ reader readFile: fileName ]) {
        @try {
            while ([reader parseNextLine]) {
                if ([reader columnCount] < 10) {
                    continue;
                }
                @try {
                    int x = 0;
                    PSItem* item = [[PSItem alloc] init];
                    if (item == nil) {
                        NSException *exception = [[NSException alloc]initWithName:@"memoryerror" reason:@"nil" userInfo:nil];
                        [exception raise];
                    }
                    item.itemType = itemType;
                    item.name = [reader columnAtIndex: x++];
                    item.genderType = [[reader columnAtIndex: x++] intValue];
                    item.hunterType = [[reader columnAtIndex: x++] intValue];
                    item.rareRank = [[reader columnAtIndex: x++] intValue];
                    item.slotCount = [[reader columnAtIndex: x++] intValue];
                    item.existHunterRank = [[reader columnAtIndex: x++] intValue];
                    item.existTownRank = [[reader columnAtIndex: x++] intValue];
                    item.defInitial = [[reader columnAtIndex: x++] intValue];
                    item.defMax = [[reader columnAtIndex: x++] intValue];
                    item.shellFire = [[reader columnAtIndex: x++] intValue];
                    item.shellWater = [[reader columnAtIndex: x++] intValue];
                    item.shellIce = [[reader columnAtIndex: x++] intValue];
                    item.shellThunder = [[reader columnAtIndex: x++] intValue];
                    item.shellDragon = [[reader columnAtIndex: x++] intValue];
                    
                    for (int i = 0; x + 1 < [reader columnCount] && i < 5; ++i) {
                        NSString *name = [reader columnAtIndex: x ++];
                        int point = [[reader columnAtIndex: x ++] intValue];
                        if ([name length] == 0) {
                            continue;
                        }
                        if ([name isEqual: @"胴系統複製"] || [name isEqual: @"胴系統倍加"] || [name isEqual: @"胴系統倍化"]) {
                            item.isCopieSkill = YES;
                            continue;
                        }
                        Repository* repo = [Repository mainRepository];
                        SkillKind *kind = [repo.skillDB findSkillKindByName: name];
                        [item.skills set:kind :point :TRUE];
                    }

                    PSItemMaterial* material = [[PSItemMaterial alloc]init];
                    for(int i = 0; x + 1 < [reader columnCount] && i < 4; ++ i) {
                        NSString* name = [reader columnAtIndex: x ++];
                        //name = [reader intern:name];
                        int count = [[reader columnAtIndex: x ++] intValue];
                        
                        if ([name length] == 0) {
                            continue;
                        }
                        
                        [material addItem:name itemCount:count];
                    }
                    if (material.count > 0) {
                        item.materialA = material;
                    }
                    [material release];
                    [list addObject: item];
                }
                @catch (NSException *exception) {
                    NSLog(@"exception %@ %@", exception, [exception callStackSymbols]);
                }
                @finally {
                }
            }
            
        }
        @catch (NSException *exception) {
            NSLog(@"exception %@ %@", exception, [exception callStackSymbols]);
        }
        @finally {
            [ reader release ];
        }
    }
    return list;
}

-(void)readSkillFukugo:(NSString*)fileName {
    LineReader* in = [[LineReader alloc]init];
    
    if ([in readFile:fileName] == FALSE) {
        return;
    }
    @try {
        Repository* repo = [Repository mainRepository];
        SkillDB* categories = repo.skillDB;
        SkillFukugo* fukugo = repo.fukugo;
        
        while ([in parseNextLine]) {
            if (in.columnCount < 2) {
                continue;
            }
            NSString* nameFukugo = [in columnAtIndex: 0];
            SkillPoint* pointFukugo = [categories pointNameToPoint:nameFukugo];
            if (pointFukugo == nil) {
                continue;
            }
            
            NSMutableArray* listPoint = [[NSMutableArray alloc]init];
            for (int i = 1; i < in.columnCount; ++ i) {
                NSString* name2 = [in columnAtIndex:i];
                SkillPoint* point2 = [categories pointNameToPoint:name2];
                if (point2 == nil) {
                    continue;
                }
                [listPoint addObject:point2];
            }
            
            [fukugo.mapFukugo setObject:listPoint forKey:pointFukugo];
        }
    }
    @catch (NSException *exception) {
        NSLog(@"exception %@ %@", exception, [exception callStackSymbols]);
    }
    @finally {
        [in release];
    }
}

-(NSMutableArray*)readDecorationCSV:(NSString*)fileName:(int)itemType {
    LineReader* in = [[LineReader alloc]init];
    NSMutableArray *result = [[NSMutableArray alloc]init];
    
    Repository * repo = [Repository mainRepository];
    SkillDB* skillDB = repo.skillDB;
    
    @try {
        if ([in readFile: fileName] == FALSE) {
            return nil;
        }
        while ([in parseNextLine]) {
            int x = 0;
            
            if (in.columnCount < 5) {
                continue;
            }

            NSString* name = [in columnAtIndex:x ++];
            if (name.length >= 1) {
                NSString *sub = [name substringToIndex:1];
                if ([sub isEqual: @"#"]) {
                    [sub release];
                    continue;
                }
                [sub release];
            }
            PSItem* item = [[PSItem alloc]init];
            item.name = [StringHolder intern: name];
            item.rareRank = [in columnAtIndex: x ++].intValue;
            item.slotCount = [in columnAtIndex: x ++].intValue;
            item.existHunterRank = [in columnAtIndex: x ++].intValue;
            item.existTownRank = [in columnAtIndex:x ++].intValue;
            item.itemType = itemType;

            for (int i = 0; i < 2 && i + x < in.columnCount; ++ i) {
                NSString* name = [in columnAtIndex:x ++];
                if (name.length == 0) {
                    x ++;
                    continue;
                }
                int point = [in columnAtIndex:x ++].intValue;
                // name ---
                if (name.length > 3) {
                    NSString* sub = [name substringToIndex:3];
                    if ([sub isEqual: @"---"]) {
                        [sub release];
                        continue;
                    }
                    [sub release];
                }
                SkillKind* kind = [skillDB findSkillKindByName:name];
                [item.skills set:kind :point :TRUE];
            }
            
            item.materialA = [[PSItemMaterial alloc]init];
            for (int i = 0; i < 4 && i + x < in.columnCount; ++ i) {
                NSString* name = [in columnAtIndex:x ++];
                //name = [in intern:name];
                int count = [in columnAtIndex:x ++].intValue;
                if (name.length > 0) {
                    name = [StringHolder intern:name];
                    [item.materialA addItem:name itemCount:count];
                    continue;
                }
            }
            item.materialB = [[PSItemMaterial alloc]init];
            for (int i = 0; i < 4 && i + x < in.columnCount; ++ i) {
                NSString* name = [in columnAtIndex:x ++];
                //name = [in intern:name];
                int count = [in columnAtIndex:x ++].intValue;
                if (name.length > 0) {
                    name = [StringHolder intern:name];
                    [item.materialB addItem:name itemCount:count];
                    continue;
                }
            }
            
            [result addObject:item];
            [item release];
        }
    }
    @catch (NSException *exception) {
        NSLog(@"exception %@ %@", exception, [exception callStackSymbols]);
    }
    @finally {
        [in release];
    }
    return result;
}

@end
