//
//  Defintion.m
//
//  Created by Z  on 16/4/11
//  Copyright (c) 2016 __MyCompanyName__. All rights reserved.
//

#import "Defintion.h"
#import "Orders.h"
#import "Conditions.h"


NSString *const kDefintionPageSize = @"pageSize";
NSString *const kDefintionOrders = @"orders";
NSString *const kDefintionConditions = @"conditions";
NSString *const kDefintionProbePages = @"probePages";
NSString *const kDefintionPage = @"page";


@interface Defintion ()

- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;

@end

@implementation Defintion

@synthesize pageSize = _pageSize;
@synthesize orders = _orders;
@synthesize conditions = _conditions;
@synthesize probePages = _probePages;
@synthesize page = _page;


+ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
{
    return [[self alloc] initWithDictionary:dict];
}

- (instancetype)initWithDictionary:(NSDictionary *)dict
{
    self = [super init];
    
    // This check serves to make sure that a non-NSDictionary object
    // passed into the model class doesn't break the parsing.
    if(self && [dict isKindOfClass:[NSDictionary class]]) {
            self.pageSize = [self objectOrNilForKey:kDefintionPageSize fromDictionary:dict];
    NSObject *receivedOrders = [dict objectForKey:kDefintionOrders];
    NSMutableArray *parsedOrders = [NSMutableArray array];
    if ([receivedOrders isKindOfClass:[NSArray class]]) {
        for (NSDictionary *item in (NSArray *)receivedOrders) {
            if ([item isKindOfClass:[NSDictionary class]]) {
                [parsedOrders addObject:[Orders modelObjectWithDictionary:item]];
            }
       }
    } else if ([receivedOrders isKindOfClass:[NSDictionary class]]) {
       [parsedOrders addObject:[Orders modelObjectWithDictionary:(NSDictionary *)receivedOrders]];
    }

    self.orders = [NSArray arrayWithArray:parsedOrders];
    NSObject *receivedConditions = [dict objectForKey:kDefintionConditions];
    NSMutableArray *parsedConditions = [NSMutableArray array];
    if ([receivedConditions isKindOfClass:[NSArray class]]) {
        for (NSDictionary *item in (NSArray *)receivedConditions) {
            if ([item isKindOfClass:[NSDictionary class]]) {
                [parsedConditions addObject:[Conditions modelObjectWithDictionary:item]];
            }
       }
    } else if ([receivedConditions isKindOfClass:[NSDictionary class]]) {
       [parsedConditions addObject:[Conditions modelObjectWithDictionary:(NSDictionary *)receivedConditions]];
    }

    self.conditions = [NSArray arrayWithArray:parsedConditions];
            self.probePages = [self objectOrNilForKey:kDefintionProbePages fromDictionary:dict];
            self.page = [self objectOrNilForKey:kDefintionPage fromDictionary:dict];

    }
    
    return self;
    
}

- (NSDictionary *)dictionaryRepresentation
{
    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
    [mutableDict setValue:self.pageSize forKey:kDefintionPageSize];
    NSMutableArray *tempArrayForOrders = [NSMutableArray array];
    for (NSObject *subArrayObject in self.orders) {
        if([subArrayObject respondsToSelector:@selector(dictionaryRepresentation)]) {
            // This class is a model object
            [tempArrayForOrders addObject:[subArrayObject performSelector:@selector(dictionaryRepresentation)]];
        } else {
            // Generic object
            [tempArrayForOrders addObject:subArrayObject];
        }
    }
    [mutableDict setValue:[NSArray arrayWithArray:tempArrayForOrders] forKey:kDefintionOrders];
    NSMutableArray *tempArrayForConditions = [NSMutableArray array];
    for (NSObject *subArrayObject in self.conditions) {
        if([subArrayObject respondsToSelector:@selector(dictionaryRepresentation)]) {
            // This class is a model object
            [tempArrayForConditions addObject:[subArrayObject performSelector:@selector(dictionaryRepresentation)]];
        } else {
            // Generic object
            [tempArrayForConditions addObject:subArrayObject];
        }
    }
    [mutableDict setValue:[NSArray arrayWithArray:tempArrayForConditions] forKey:kDefintionConditions];
    [mutableDict setValue:self.probePages forKey:kDefintionProbePages];
    [mutableDict setValue:self.page forKey:kDefintionPage];

    return [NSDictionary dictionaryWithDictionary:mutableDict];
}

- (NSString *)description 
{
    return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
}

#pragma mark - Helper Method
- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
{
    id object = [dict objectForKey:aKey];
    return [object isEqual:[NSNull null]] ? nil : object;
}


#pragma mark - NSCoding Methods

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];

    self.pageSize = [aDecoder decodeObjectForKey:kDefintionPageSize];
    self.orders = [aDecoder decodeObjectForKey:kDefintionOrders];
    self.conditions = [aDecoder decodeObjectForKey:kDefintionConditions];
    self.probePages = [aDecoder decodeObjectForKey:kDefintionProbePages];
    self.page = [aDecoder decodeObjectForKey:kDefintionPage];
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{

    [aCoder encodeObject:_pageSize forKey:kDefintionPageSize];
    [aCoder encodeObject:_orders forKey:kDefintionOrders];
    [aCoder encodeObject:_conditions forKey:kDefintionConditions];
    [aCoder encodeObject:_probePages forKey:kDefintionProbePages];
    [aCoder encodeObject:_page forKey:kDefintionPage];
}

- (id)copyWithZone:(NSZone *)zone
{
    Defintion *copy = [[Defintion alloc] init];
    
    if (copy) {

        copy.pageSize = self.pageSize;
        copy.orders = [self.orders copyWithZone:zone];
        copy.conditions = [self.conditions copyWithZone:zone];
        copy.probePages = self.probePages;
        copy.page = self.page;
    }
    
    return copy;
}


@end
