//
//  PSItem.m
//  MHP3SkillSim

#import "PSItem.h"
#import "PSMutex.h"
#import "Repository.h"

static int _staticSeq = 0;

@implementation PSItem

@synthesize seq = _seq;
@synthesize itemType = _itemType;
@synthesize name = _name;
@synthesize skills = _skills;
@synthesize genderType = _genderType;
@synthesize hunterType = _hunterType;
@synthesize rareRank = _rareRank;
@synthesize slotCount = _slotCount;
@synthesize existHunterRank = _existHunterRank;
@synthesize existTownRank = _existTownRank;
@synthesize defInitial = _defInitial;
@synthesize defMax = _defMax;
@synthesize shellFire = _shellFire;
@synthesize shellWater = _shellWater;
@synthesize shellIce = _shellIce;
@synthesize shellThunder = _shellThunder;
@synthesize shellDragon = _shellDragon;
@synthesize isCopieSkill = _isCopieSkill;
@synthesize materialA = _materialA;
@synthesize materialB = _materialB;
@synthesize viewFound = _viewFound;
@synthesize viewCount = _viewCount;
@synthesize isVirtual = _isVirtual;
//@synthesize isVirtualNone = _isVirtualNone;
@synthesize isCheckedForSearch = _isCheckedForSearch;
@synthesize isCheckedForView = _isCheckedForView;
@synthesize charmStone = _charmStone;
@synthesize charmTable = _charmTable;

- (id)init
{
    self = [super init];
    if (self) {
        _seq = _staticSeq ++;
        _skills = [[SkillSet alloc]init];
        _isCheckedForSearch = TRUE;
        _isCheckedForView = TRUE;
    }else {
        [[PSMutex mainMutex] raiseMemoryError];
    }
    [[PSMutex mainMutex] showMemoryAlertIfError];
    return self;
}

-(void)dealloc
{
    [_name release];
    [_skills release];
    [_materialA release];
    [_materialB release];
    [super dealloc];
}

- (NSString*) description
{
    return [[NSString alloc]initWithFormat:@"%@[%d]", _name, _slotCount];
}

-(PSItem *)item {
    NSException *exception = [[NSException alloc]initWithName:@"memoryerror" reason:@"nil" userInfo:nil];
    [exception raise];
    return nil;
}

-(void)printContents:(NSMutableString*)string {
    NSMutableString* text = string;
    
    [ text appendFormat: @"%@ HR[%d] / 村:[%d]\n", _name, _existHunterRank, _existTownRank ];
    [ text appendFormat: @"Rare[%d][%@ %@]\n", _rareRank, [PSItemType genderTypeText: _genderType], [PSItemType hunterTypeText: _hunterType ] ];
    if (_itemType != ITEM_TYPE_CHARM && _itemType != ITEM_TYPE_DECORATION) {
        [ text appendFormat: @"防[%d (未強化%d)]\n", _defMax, _defInitial ];
    }
    [ text appendFormat: @"スロ[%d]\n", _slotCount ];
    
    if (_itemType != ITEM_TYPE_CHARM && _itemType != ITEM_TYPE_DECORATION) {
        [text appendFormat: @"[火%d水%d氷%d雷%d龍%d]\n", _shellFire, _shellWater, _shellIce, _shellThunder, _shellDragon ];
    }
    
    [text appendString: @"スキルポイント:"];
    if (self.isCopieSkill) {
        [text appendString:@"{胴系統複製}\n"]; 
    }else {
        [_skills skillToString:text :nil :FALSE];
        [text appendFormat: @"\n"];
    }
    
    if (_itemType != ITEM_TYPE_CHARM) {
        if (_materialA != nil) {
            [text appendFormat:@"素材一覧{\n"];
            for(int i = 0; i < _materialA.count; ++ i) {
                [text appendFormat:@"　%@x%d\n"
                 , [_materialA itemNameAtIndex:i]
                 , [_materialA itemCountAtIndex:i] ];
            }
            [text appendFormat:@"}\n"];

            if (_materialB != nil && _materialB.count > 0) {
                [text appendFormat:@"素材一覧その２{\n"];
                for(int i = 0; i < _materialB.count; ++ i) {
                    [text appendFormat:@"　%@x%d\n"
                     , [_materialB itemNameAtIndex:i]
                     , [_materialB itemCountAtIndex:i] ];
                }
                [text appendFormat:@"}\n"];
            }
        }
    }
    /*
    if (itemType == PSItemType.TYPE_CHARM && charmGroup != null) {
        str.append("同等/上位お守り{" + charmGroup.listCharm.size() + " pattern " + LF);
        for (Charm charm : charmGroup.listCharm) {
            str.append("　" + charm.toString() + LF);
        }
        str.append("}" + LF);
    }    
     */
}

-(NSString*)cellLabel
{
    return _name;
}
/*
-(BOOL)isTargetSameSkillsAndSlot:(PSItem *)grp
{
    if (self.isCopieSkill) {
        if (grp.isCopieSkill) {
            return YES;
        }
        return NO;
    }else if (grp.isCopieSkill) {
        return NO;
    }
    
    if (self.slotCount == grp.slotCount) {
        if ([SkillSet compareSkillSet:self.maskedSkills to:grp.maskedSkills] == 0) {
            return YES;
        }
    }
    
    return NO;
}*/

/*
 -(BOOL)isTargetWeakChildren:(PSItem*)grp search:(SkillSet*)searchSkills
{
    if (self.isCopieSkill || grp.isCopieSkill) {
        return NO;
    }
    if (self.slotCount < grp.slotCount) {
        return NO;
    }
    if ([self isTargetSameSkillsAndSlot:grp]) {
        return NO;
    }
    
    SkillSet* skills = self.maskedSkills;
    SkillSet* target = grp.maskedSkills;
    
    for(int i = 0; i < searchSkills.count; ++i ){
        SkillKind* kind = [searchSkills.listKind objectAtIndex: i];
        
        int x1 = [skills findByKind: kind];
        int x2 = [target findByKind: kind];
        
        if (x1 < 0 && x2 < 0) {
            continue;
        }
        if (x1 < 0) {
            return NO;
        }
        if (x2 < 0) {
            continue;
        }
        if (skills.positive[x1]) {
            if (skills.point[x1] < target.point[x2]) {
                return NO;
            }
        }else {
            if (skills.point[x1] > target.point[x2]) {
                return NO;
            }
        }
    }
    return YES;
}*/

-(NSUInteger)hash {
    return _name.hash + _itemType * 100;
}

-(BOOL)isEqual:(id)object {
    NSObject* obj = object;
    if (self.hash == obj.hash) {
        if ([PSItem comparePSItem:self to:object] == 0) {
            return TRUE;
        }
    }
    return FALSE;
}

-(void)getArmorNameAndSlot:(NSMutableString*) str {
    PSItem* item = self;
    /*if (item.isVirtualNone) {
        [str appendString: item.name];
    }else*/ if (item.isCopieSkill && item.isVirtual) {
        [str appendFormat: @"{胴系統複製}"];
    }else if (item.itemType == ITEM_TYPE_CHARM) {
        [str appendString: item.name];
        [item.skills skillToString:str :nil :TRUE];
        [str appendFormat:@"【%d】", item.slotCount];
    }else if (item.itemType == ITEM_TYPE_DECORATION) {
        [str appendFormat:@"%@", item.name];
    }else {
        [str appendFormat:@"%@【%d】", item.name, item.slotCount];
    }
}

-(void)getArmorName:(NSMutableString*) str {
    PSItem* item = self;
    /*if (item.isVirtualNone) {
        [str appendString: item.name];
    }else*/ if (item.isCopieSkill && item.isVirtual) {
        [str appendFormat: @"{胴系統複製}"];
    }else if (item.itemType == ITEM_TYPE_CHARM) {
        [str appendString: item.name];
        [item.skills skillToString:str :nil :TRUE];
        [str appendFormat:@"【%d】", item.slotCount];
    }else {
        [str appendString: item.name];
    }
}

static NSMutableArray* cachedVirtual = nil;

+(PSItem*)getVirtualItem:(int) itemType: (int) slotCount {
    slotCount += (-VIRTUAL_START);
    if (cachedVirtual == nil) {
        cachedVirtual = [[NSMutableArray alloc]init];
    }
    
    while (cachedVirtual.count <= itemType) {
        NSMutableArray* array = [[NSMutableArray alloc]init];
        [cachedVirtual addObject: array];
    }

    NSMutableArray* list = [cachedVirtual objectAtIndex:itemType];

    if (list.count == 0) {
        for (int i = VIRTUAL_START; i <= VIRTUAL_END; ++i) {
            PSItem* item = nil;
            switch (i) {
                case VIRTUAL_COPIE:
                    item = [[PSItem alloc]init];
                    item.itemType = itemType;
                    item.name = @"{胴系統複製}";
                    item.isCopieSkill = true;
                    break;
                case VIRTUAL_SLOT0:
                    item = [[PSItem alloc]init];
                    item.itemType = itemType;
                    /*if (itemType == ITEM_TYPE_CHARM) {
                        item.name = @"スロット０";
                    }else*/ {
                        item.name = @"なし";
                    }
                    item.slotCount = 0;
                    break;
                case VIRTUAL_SLOT1:
                    item = [[PSItem alloc]init];
                    item.itemType = itemType;
                    item.name = @"スロット１";
                    item.slotCount = 1;
                    break;
                case VIRTUAL_SLOT2:
                    item = [[PSItem alloc]init];
                    item.itemType = itemType;
                    item.name = @"スロット２";
                   item.slotCount = 2;
                    break;
                case VIRTUAL_SLOT3:
                    item = [[PSItem alloc]init];
                    item.itemType = itemType;
                    item.name = @"スロット３";
                    item.slotCount = 3;
                    break;
                case VIRTUAL_EMPTY1:
                    item = [[PSItem alloc]init];
                    item.itemType = itemType;
                    item.name = @"空き【1】";
                    item.slotCount = 1;
                    break;
                case VIRTUAL_EMPTY2:
                    item = [[PSItem alloc]init];
                    item.itemType = itemType;
                    item.name = @"空き【2】";
                    item.slotCount = 1;
                    break;
                case VIRTUAL_EMPTY3:
                    item = [[PSItem alloc]init];
                    item.itemType = itemType;
                    item.name = @"空き【3】";
                    item.slotCount = 1;
                    break;
            }
            item.isVirtual = TRUE;
            [list addObject: item];
        }
    }
    PSItem* item = [list objectAtIndex:slotCount];
    while (item.retainCount < 10) {
        [item retain];
    }
    return item;
}

+(PSItem*)getInstanceByName:(int)itemType: (NSString*) name {
    PSItem* found = nil;
    NSMutableArray* itemList = nil;
    Repository* repo = [Repository mainRepository];
    PSBaseItems* datas = [repo items];
    switch (itemType) {
        case ITEM_TYPE_HEAD:
            itemList = datas.listEquipHead;
            break;
        case ITEM_TYPE_BODY:
            itemList = datas.listEquipBody;
            break;
        case ITEM_TYPE_ARM:
            itemList = datas.listEquipArm;
            break;
        case ITEM_TYPE_WEIST:
            itemList = datas.listEquipWeist;
            break;
        case ITEM_TYPE_LEG:
            itemList = datas.listEquipLeg;
            break;
        case ITEM_TYPE_CHARM:
            itemList = nil;
            break;
        case ITEM_TYPE_DECORATION:
            itemList = datas.listDecoration;
            break;
        default:
            return nil;
    }
    for (int slotCount = VIRTUAL_START; slotCount <= VIRTUAL_END; ++slotCount) {
        PSItem* item = [PSItem getVirtualItem: itemType: slotCount];
        if ([item.name isEqual:name]) {
            found = item;
            break;
        }
    }
    if (found == nil && itemType != ITEM_TYPE_CHARM) {
        for (int i = 0; i < itemList.count; ++ i) {
            PSItem* item = [itemList objectAtIndex:i];
            if ([item.name isEqual: name]) {
                found = item;
                break;
            }
        }
    }
    return found;
}

+(int)comparePSItem:(id)a to:(id)b {
    if (a == b) {
        return 0;
    }
    if (a == nil) {
        return -1;
    }
    if (b == nil) {
        return 1;
    }
    
    PSItem* that = a;
    PSItem* item = b;
    
    int x = 0;
    
    if (x == 0) {
        x = that.itemType - item.itemType;
    }
    
    if (x == 0) {
        if (that.isVirtual == false && item.isVirtual == false && that.itemType != ITEM_TYPE_CHARM) {
            x = that.seq - item.seq;
        }
    }
    
    if (x == 0) {
        NSComparisonResult res = [that.name compare:item.name];
        x = res;
    }

    if (x == 0) {
        x = that.rareRank - item.rareRank;
    }
    
    if (x == 0) {
        x = that.genderType - item.genderType;
    }
    
    if (x == 0) {
        x = that.hunterType - item.hunterType;
    }
    
    if (x == 0) {
        x = that.slotCount - item.slotCount;
    }
    
    if (x == 0) {
        x = [SkillSet compareSkillSet:that.skills to:item.skills];
    }
    
    if (x < 0) {
        return -1;
    }
    if (x > 0) {
        return 1;
    }
    return 0;
}

-(id)copyWithZone:(NSZone *)zone {
    [self retain];
    return self;
}

+(void)clearEveryViewCount {
    Repository* repo = [Repository mainRepository];
    PSBaseItems* items = repo.items;
    for (int i = ITEM_TYPE_HEAD; i <= ITEM_TYPE_DECORATION; ++ i) {
        NSMutableArray* list = [items arrayByType:i];
        for (int j = 0; j < list.count; ++ j) {
            PSItem* item = [list objectAtIndex:j];
            item.viewCount = 0;
        }
        for (int j = VIRTUAL_START; j <= VIRTUAL_END; ++ j) {
            PSItem* item = [PSItem getVirtualItem:i :j];
            item.viewCount = 0;
        }
    }
}

+(void)clearEveryViewFound {
    Repository* repo = [Repository mainRepository];
    PSBaseItems* items = repo.items;
    for (int i = ITEM_TYPE_HEAD; i <= ITEM_TYPE_DECORATION; ++ i) {
        NSMutableArray* list = [items arrayByType:i];
        for (int j = 0; j < list.count; ++ j) {
            PSItem* item = [list objectAtIndex:j];
            item.viewFound = FALSE;
        }
        for (int j = VIRTUAL_START; j <= VIRTUAL_END; ++ j) {
            PSItem* item = [PSItem getVirtualItem:i :j];
            item.viewFound = 0;
        }
    }
}

@end
