//
//  usblisterAppDelegate.m
//  usblister
//
//  Created by Rex Feany on 4/8/11.
//  Copyright 2011 Fnordsoft, Inc. All rights reserved.
//

#import "usblisterAppDelegate.h"

#include <stdio.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDKeys.h>
#include <CoreFoundation/CoreFoundation.h>

#import "OutlineData.h"

@implementation usblisterAppDelegate

@synthesize window;
@synthesize field;
@synthesize button;
@synthesize hash_a;
@synthesize array_a;
@synthesize tabs;
@synthesize data;
@synthesize outline;

static NSArray *kv_pair(NSString *key, id value)
{
    return [NSArray arrayWithObjects:key, value, nil];
}
                                                
static NSArray *dict_to_array(NSDictionary *d)
{
    NSMutableArray *a = [NSMutableArray array];
    [d enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
	    if ([obj isKindOfClass:[NSDictionary class]]) {
            obj = dict_to_array(obj);
	    }
	    [a addObject:kv_pair(key, obj)];
	}
    ];
    return a;
}

static BOOL iterate(NSMutableArray *hash_a, NSMutableArray *array_a, const io_name_t plane) {
    IOReturn result;
    io_iterator_t hidObjectIterator = 0;
    io_object_t hidDevice = IO_OBJECT_NULL;
    CFMutableDictionaryRef hidProperties = 0;
    
    result = IORegistryCreateIterator(kIOMasterPortDefault, kIOUSBPlane, kIORegistryIterateRecursively, &hidObjectIterator);
    
    if ((result != kIOReturnSuccess) || (hidObjectIterator == 0)) {
        NSLog(@"Can't obtain an IO iterator\n");
        return NO;
    }
    
    while ((hidDevice = IOIteratorNext(hidObjectIterator))) {
        hidProperties = 0;
        result = IORegistryEntryCreateCFProperties(hidDevice, &hidProperties,
                                                   kCFAllocatorDefault, kNilOptions);
        if ((result == KERN_SUCCESS) && hidProperties) {
            NSDictionary *d = (NSDictionary *)hidProperties;
            NSString *s = [d objectForKey:@"USB Product Name"];
            
            if (s) {
                CFRetain(hidProperties);
                [hash_a addObject:d];
                [array_a addObject:kv_pair(s, dict_to_array(d))];
            }
        }
        IOObjectRelease(hidDevice);
    }
    IOObjectRelease(hidObjectIterator);
    return YES;
}

static BOOL magic(NSMutableArray *hash_a, NSMutableArray *array_a) {
    [hash_a removeAllObjects];
    [array_a removeAllObjects];
    
    if (!iterate(hash_a, array_a, kIOUSBPlane)) return NO;
    
    return YES;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    [self performSelector:@selector(scanClick:) withObject:nil afterDelay:.3];
    NSLog(@"wtf");
}

- (IBAction)scanClick:(id)sender {
    if (self.hash_a == nil) {
        self.hash_a = [NSMutableArray array];
    }
    if (self.array_a == nil) {
        self.array_a = [NSMutableArray array];
    }
    if (self.data == nil) {
        self.data = [[OutlineData alloc] init];
        self.data.data = self.array_a;
        [self.outline setDataSource:self.data];
    }
    magic(self.hash_a, self.array_a);
    [self.field setString:[NSString stringWithFormat:@"%@", self.hash_a]];
    [self.outline reloadData];
}

- (IBAction)saveClick:(id)sender {
    NSSavePanel *spanel = [NSSavePanel savePanel];
    NSArray *array = [NSArray arrayWithObject:@"txt"];
    
    [spanel setAllowedFileTypes:array];    
    
    if ([spanel runModal] == NSFileHandlingPanelOKButton) {
        NSString *str = [self.field string];
        [str writeToURL:[spanel URL] atomically:FALSE encoding:NSASCIIStringEncoding error:NULL];
    }
}

- (BOOL)textView:(NSTextView *)aTextView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString {
    return NO;
}


@end

