//
//  RMHeapStackDetailTableViewController.m
//  HeapInspectorExample
//
//  Created by Christian Menschel on 29.08.14.
//  Copyright (c) 2014 tapwork. All rights reserved.
//

#import "HINSPHeapStackDetailTableViewController.h"
#import "HINSPResponderChainViewController.h"
#import "HINSPShowViewController.h"
#import "HINSPTableViewCell.h"
#import "HINSPClassDumpTableViewController.h"
#import "HINSPRefHistoryTableViewController.h"
#import "NSObject+HeapInspector.h"

static NSString *const kCellTitleShow = @"Show";
static NSString *const kCellTitleResponderChain = @"Responder Chain";
static NSString *const kCellTitleMethods = @"Methods";
static NSString *const kCellTitleReferenceHistory = @"Reference History";
static NSString *const kCellTitleIvars = @"iVars";
static NSString *const kCellTitleProperties = @"Properties";
static NSString *const kCellTitleRecursiveDesc = @"Recursive Description";

static const CGFloat kHeaderViewHeight = 100.0f;

@interface HINSPHeapStackDetailTableViewController ()

@end

@implementation HINSPHeapStackDetailTableViewController
{
    UITextView *_headerTextView;
    UIFont *_boldFont;
    UIFont *_regFont;
}

#pragma mark - View Life Cycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.title = @"Object Inspector";
    _boldFont = [UIFont boldSystemFontOfSize:12];
    _regFont = [UIFont systemFontOfSize:12];
    
    [self setupHeaderView];
    [self prepareDataSource];
}

- (void)setupHeaderView
{
    CGRect headerViewFrame = CGRectMake(0.0, 0.0,
                                        self.tableView.bounds.size.width,
                                        kHeaderViewHeight);
    UIView *headerView = [[UIView alloc] initWithFrame:headerViewFrame];
    headerView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
    
    CGRect titleLabelFrame = CGRectMake(5.0, 5.0,
                                        headerView.bounds.size.width - 10.0,
                                        15.0);
    UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleLabelFrame];

    CGRect textViewFrame = CGRectMake(0.0, CGRectGetMaxY(titleLabel.frame),
                                      headerView.bounds.size.width,
                                      headerView.bounds.size.height - CGRectGetMaxY(titleLabel.frame));
    UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame];

    titleLabel.text = [NSString stringWithFormat:@"%s: %p",
                       object_getClassName(self.inspectingObject),
                       self.inspectingObject];
    titleLabel.font = [UIFont boldSystemFontOfSize:12];
    titleLabel.backgroundColor = [UIColor clearColor];
    [headerView addSubview:titleLabel];
    
    // Add a switch if the object is of bool type
    if ([self.inspectingObject respondsToSelector:@selector(boolValue)] &&
        [NSStringFromClass([self.inspectingObject class]) isEqualToString:@"__NSCFBoolean"]) {
        UISwitch *boolSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
        CGRect switchFrame = boolSwitch.frame;
        switchFrame.origin.x = headerViewFrame.size.width - switchFrame.size.width - 10.0;
        switchFrame.origin.y = 5.0;
        boolSwitch.frame = switchFrame;
        [boolSwitch addTarget:self action:@selector(boolSwitchToggle:) forControlEvents:UIControlEventValueChanged];
        boolSwitch.on = [self.inspectingObject boolValue];
        [headerView addSubview:boolSwitch];
    }
    
    textView.editable = NO;
    textView.backgroundColor = [UIColor clearColor];
    _headerTextView = textView;
    [headerView addSubview:textView];
    
    textView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    headerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    
    self.tableView.tableHeaderView = headerView;
    [self updateHeaderView];
}

- (void)updateHeaderView
{
    if ([self.inspectingObject conformsToProtocol:@protocol(NSObject)] &&
         [self.inspectingObject respondsToSelector:@selector(description)]) {
        _headerTextView.text = [self.inspectingObject description];
    }
}

#pragma mark - Actions

- (void)boolSwitchToggle:(UISwitch *)boolSwitch
{
    self.inspectingObject = @(boolSwitch.on);
    [self updateHeaderView];
}

#pragma mark - DataSource

- (void)prepareDataSource
{
    NSMutableArray *dataSource = [@[] mutableCopy];
    
    NSArray *refHistory = [NSObject referenceHistoryForObject:self.inspectingObject];
    if ([refHistory count]) {
        [dataSource addObject:kCellTitleReferenceHistory];
    }
    
    if ([self.inspectingObject isKindOfClass:[UIResponder class]]) {
        [dataSource addObject:kCellTitleResponderChain];
    }
    if ([self.inspectingObject isKindOfClass:[UIView class]] ||
        [self.inspectingObject isKindOfClass:[UIImage class]] ||
        [self.inspectingObject isKindOfClass:[UIViewController class]]) {
        [dataSource addObject:kCellTitleShow];
        if ([self.inspectingObject isKindOfClass:[UIView class]]) {
             [dataSource addObject:kCellTitleRecursiveDesc];
        }
    }
    
    [dataSource addObject:kCellTitleMethods];
    [dataSource addObject:kCellTitleProperties];
    [dataSource addObject:kCellTitleIvars];
    
    self.dataSource = dataSource;
    [self.tableView reloadData];
}

#pragma mark - UITableview dataSource & Delegate

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kTableViewCellIdent
                                                            forIndexPath:indexPath];
    
    NSString *item = self.dataSource[indexPath.row];
    cell.textLabel.text = item;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    if ([item isEqualToString:kCellTitleReferenceHistory]) {
        cell.textLabel.font = _boldFont;
    } else {
        cell.textLabel.font = _regFont;
    }
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIViewController *targetController = nil;
    NSString *item = self.dataSource[indexPath.row];
    if ([item isEqualToString:kCellTitleResponderChain]) {
        targetController = [[HINSPResponderChainViewController alloc] initWithObject:self.inspectingObject];
    } else if ([item isEqualToString:kCellTitleShow]) {
        targetController = [[HINSPShowViewController alloc] initWithObject:self.inspectingObject];
    } else if ([item isEqualToString:kCellTitleMethods]) {
        targetController = [[HINSPClassDumpTableViewController alloc] initWithObject:self.inspectingObject type:RMClassDumpMethods];
    } else if ([item isEqualToString:kCellTitleIvars]) {
        targetController = [[HINSPClassDumpTableViewController alloc] initWithObject:self.inspectingObject type:RMClassDumpIvar];
    } else if ([item isEqualToString:kCellTitleProperties]) {
        targetController = [[HINSPClassDumpTableViewController alloc] initWithObject:self.inspectingObject type:RMClassDumpProperties];
    } else if ([item isEqualToString:kCellTitleRecursiveDesc]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
        NSString *recursiveDesc = [self.inspectingObject performSelector:@selector(recursiveDescription)];
        targetController = [[HINSPShowViewController alloc] initWithObject:recursiveDesc];
        ((HINSPShowViewController *)targetController).shouldShowEditButton = NO;
    } else if ([item isEqualToString:kCellTitleReferenceHistory]) {
        targetController = [[HINSPRefHistoryTableViewController alloc] initWithObject:self.inspectingObject];
    }
#pragma clang diagnostic pop
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    [self.navigationController pushViewController:targetController animated:YES];
}


@end
