/*
 * Copyright [2019] [Doric.Pub]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//
//  DoricHLayoutNode.m
//  Doric
//
//  Created by pengfei.zhou on 2019/7/30.
//

#import "DoricHLayoutNode.h"
#import "DoricUtil.h"

@implementation DoricHLayoutNode
- (instancetype)init {
    if (self = [super init]) {
        _space = 0;
        _gravity = 0;
    }
    return self;
}

- (void)blendView:(id)view forPropName:(NSString *)name propValue:(id)prop {
    if ([name isEqualToString:@"gravity"]) {
        self.gravity = [(NSNumber *)prop integerValue];
    } else if ([name isEqualToString:@"space"]) {
        self.space = [(NSNumber *)prop floatValue];
    } else {
        [super blendView:view forPropName:name propValue:prop];
    }
}

- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig {
    [super blendChild:child layoutConfig:layoutconfig];
    if (![child.layoutParams isKindOfClass:VHLayoutParams.class]) {
        DoricLog(@"blend HLayout child error,layout params not match");
        return;
    }
    VHLayoutParams *params = (VHLayoutParams *)child.layoutParams;
    NSDictionary *margin = [layoutconfig objectForKey:@"margin"];
    if (margin) {
        params.margin.top = [(NSNumber *)[margin objectForKey:@"top"] floatValue];
        params.margin.left = [(NSNumber *)[margin objectForKey:@"left"] floatValue];
        params.margin.right = [(NSNumber *)[margin objectForKey:@"right"] floatValue];
        params.margin.bottom = [(NSNumber *)[margin objectForKey:@"bottom"] floatValue];
    }
    NSNumber *alignment = [layoutconfig objectForKey:@"alignment"];
    if (alignment) {
        params.alignment = [alignment integerValue];
    }
}

- (VHLayoutParams *)generateDefaultLayoutParams {
    return [[VHLayoutParams alloc] init];
}

- (void)measureByParent:(DoricGroupNode *)parent {
    DoricLayoutDesc widthSpec = self.layoutParams.width;
    DoricLayoutDesc heightSpec = self.layoutParams.height;
    CGFloat maxWidth = 0,maxHeight = 0;
    for (DoricViewNode *child in self.indexedChildren) {
        [child measureByParent:self];
        CGFloat placeWidth = child.measuredWidth;
        CGFloat placeHeight = child.measuredHeight;
        maxWidth += placeWidth + self.space;
        maxHeight = MAX(maxHeight, placeHeight);
    }
    
    maxWidth -= self.space;
    
    self.desiredWidth = maxWidth;
    self.desiredHeight = maxHeight;
    
    if (widthSpec == LAYOUT_WRAP_CONTENT) {
        self.width = maxWidth;
    }
    
    if (heightSpec == LAYOUT_WRAP_CONTENT) {
        self.height = maxHeight;
    }
}

- (void)layoutByParent:(DoricGroupNode *)parent {
    if (self.layoutParams.width == LAYOUT_MATCH_PARENT) {
        self.width = parent.width;
    }
    if (self.layoutParams.height == LAYOUT_MATCH_PARENT) {
        self.height = parent.height;
    }
    // layout child
    CGFloat xStart = 0;
    if ((self.gravity & LEFT) == LEFT) {
        xStart = 0;
    } else if ((self.gravity & RIGHT) == RIGHT) {
        xStart = self.width - self.desiredWidth;
    } else if ((self.gravity & CENTER_X) == CENTER_X) {
        xStart = (self.width -self.desiredWidth)/2;
    }
    
    for (DoricViewNode *child in self.indexedChildren) {
        if (child.layoutParams.width == LAYOUT_MATCH_PARENT) {
            child.width = self.width;
        }
        if (child.layoutParams.height == LAYOUT_MATCH_PARENT) {
            child.height = self.height;
        }
        
        if ([child.layoutParams isKindOfClass:VHLayoutParams.class]) {
            VHLayoutParams *layoutParams = (VHLayoutParams *)child.layoutParams;
            DoricGravity gravity = layoutParams.alignment | self.gravity;
            if ((gravity & TOP) == TOP) {
                child.top = 0;
            } else if ((gravity & BOTTOM) == BOTTOM) {
                child.bottom = self.height;
            } else if ((gravity & CENTER_Y) == CENTER_Y) {
                child.centerY = self.height/2;
            }
        }
        child.left = xStart;
        xStart = child.right + self.space;
        [child layoutByParent:self];
    }
}

@end