import os
import sys
import time
import traceback


import objc
import thread



myUIKit = objc.loadBundle("UIKit", globals(), "/System/Library/Frameworks/UIKit.framework")

#From http://pyobjc.sourceforge.net/documentation/pyobjc-core/wrapping.html: "If the framework defines any (informal) protocols you should add objc.informal_protocol objects for those protocols to your module. These can be defined in a submodule, as long as you arrange for that module to be loaded whenever someone imports your package."
UIImagePickerControllerDelegate = objc.informal_protocol("UIImagePickerControllerDelegate", [
    #- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    objc.selector(None, selector="imagePickerController:didFinishPickingMediaWithInfo:", signature="v@:@@"),
    #- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
    objc.selector(None, selector="imagePickerControllerDidCancel:", signature="v@:@"),
    #- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
    objc.selector(None, selector="imagePickerController:didFinishPickingImage:editingInfo:", signature="v@:@@@")
    #objc.selector(None, selector="testMethod", signature="I@:", isRequired=1), #isClassMethod=1
])

UINavigationControllerDelegate = objc.formal_protocol("UINavigationControllerDelegate", (objc.protocolNamed("NSObject"), ), [
    #The protocol defines methods that the delegate CAN implement (NOT mandatory)
    #- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    #- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
])

#class TestBedViewController(UIViewController): #<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
class TestBedViewController(UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate):

    #- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    @objc.signature("v@:@@")
    def imagePickerController_didFinishPickingMediaWithInfo_(self, picker, info):
        try:
            print "Entered imagePickerController_didFinishPickingMediaWithInfo_(self, picker = %s, info = %s)." % (str(picker), str(info))
            sys.stdout.flush()

            picker.release()
        except:
            traceback.print_exc()
            sys.stderr.flush()

    #Provide 2.x compliance
    #- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
    @objc.signature("v@:@@@")
    def imagePickerController_didFinishPickingImage_editingInfo_(self, picker, image, editingInfo):
        try:
            #NSDictionary *dict = [NSDictionary dictionaryWithObject:image forKey:@"UIImagePickerControllerOriginalImage"];
            self.imagePickerController_didFinishPickingMediaWithInfo_(picker, dict)
        except:
            traceback.print_exc()
            sys.stderr.flush()

    #- (void) imagePickerControllerDidCancel: 
    @objc.signature("v@:@")
    def imagePickerControllerDidCancel_(self, picker):
        try:
            self.dismissModalViewControllerAnimated_(objc.YES)
            picker.release()
        except:
            traceback.print_exc()
            sys.stderr.flush()

    #- (void) snapImage: (id) sender
    @objc.signature("v@:@")
    def snapImage_(self, sender):
        print "Entered snapImage_(self, sender = %s)." % (str(sender))

        try:
            pass
        except:
            traceback.print_exc()
            sys.stderr.flush()

    #- (void) viewDidLoad
    @objc.signature("v@:")
    def viewDidLoad(self):
        try:
            if (UIImagePickerController.isSourceTypeAvailable_(1)):
                self._.navigationController._.navigationBar.setTintColor_(UIColor.colorWithRed_green_blue_alpha_(0.20392, 0.19607, 0.61176, 1.0))

            self.setTitle_(u"Image Picker")

            #thread.start_new_thread(self.MyIPC, ())
        except:
            traceback.print_exc()
            sys.stderr.flush()


UIApplicationDelegate = objc.informal_protocol("UIApplicationDelegate", [
    #- (void)applicationDidFinishLaunching:(UIApplication *)application
    objc.selector(None, selector = "applicationDidFinishLaunching:", signature = "v@:@") #ValueError: NSInvalidArgumentException - *** +[TestBedAppDelegate registerForSystemEvents]: unrecognized selector sent to class 0x2df900
])

class TestBedAppDelegate(NSObject, UIApplicationDelegate):
    @objc.signature("v@:@")
    def applicationDidFinishLaunching_(self, application):
        try:
            window = UIWindow.alloc().initWithFrame_(UIScreen.mainScreen().bounds()) #Another WORKING option: self.window = UIWindow.alloc().initWithFrame_(UIHardware.fullScreenApplicationContentRect())
            nav = UINavigationController.alloc().initWithRootViewController_(TestBedViewController.alloc().init())

            window.addSubview_(nav._.view)
            window.makeKeyAndVisible()
        except:
            traceback.print_exc()
            sys.stderr.flush()


"""
Note:
Have tried also using the standard:
    retVal = _uicaboodle.UIApplicationMain(sys.argv, TestBedAppDelegate)
and I had:
    class TestBedAppDelegate(UIApplication):
This does not solve the problem, and in fact is not how it's done in the book chapter.
"""


#From http://www.telesphoreo.org/pipermail/iphone-python/2008-July/000058.html
objc.loadBundleFunctions(myUIKit, globals(), [
    ("UIApplicationMain", "iii@@"),
])

_UIApplicationMain = UIApplicationMain
def UIApplicationMain(argv = None, principal = objc.nil, delegate = None):
    print "Entered UIApplicationMain()."
    sys.stdout.flush()

    if (argv == None):
        argv = sys.argv
    
    from ctypes import c_char_p, addressof
    argc = len(argv)
    argv = (c_char_p * argc)(*argv)
    
    if (delegate is None):
        delegate = principal

    if (principal != objc.nil):
        principal = NSString.alloc().initWithString_(principal.__name__)
    if (delegate != objc.nil):
        delegate = NSString.alloc().initWithString_(delegate.__name__)
    
    return _UIApplicationMain(argc, addressof(argv), principal, delegate)



pool = NSAutoreleasePool.alloc().init()

retVal = UIApplicationMain(sys.argv, objc.nil, TestBedAppDelegate)
print "retVal = %s" % (str(retVal))
sys.stdout.flush()

pool.release()
