 
 import CoreAudio
 
+enum HysteresisTimeoutEvent<T> {
+    /**
+     * The observed source of events has emitted a fresh event.
+     */
+    case Arrival(T)
+    
+    /**
+     * The observed source of events has gone quiet.
+     */
+    case Timeout
+}
+
+enum Weenis {
+    case Poop
+}
+
+/**
+ * RAC* uses AnyObject for its untyped references. Enums are not AnyObjet compatible,
+ * but I want to pass them through.  So, boxing it is.
+ */
+class EnumContainer<E> {
+    let value: E
+    
+    init(v: E) {
+        value = v;
+    }
+}
+
 func osStatusToString(status: OSStatus) -> String {
     // this sucks. lol objc API
     


@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    
    
    func keystrokeSignal() -> RACSignal {
        return RACSignal.createSignal({ (subscriber) -> RACDisposable! in
            NSLog("Keyboard listener created!")
            
            // TODO: how do I tear this listener down when the listener is no longer needed? Does ARC do it for me?
            NSEvent.addGlobalMonitorForEventsMatchingMask(NSEventMask.KeyDownMask, handler: { (event) -> Void in
                subscriber.sendNext(event);
            })

            NSLog("YUMMY KEYSTROKES")
        }
        
        
        // var poop = NSEvent();
        
        // bind doc: https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/ReactiveCocoa/RACSignal.m#L92
        
        var wat = keystrokeSignal().bind(everyOtherEvent).subscribeNext { (woot: AnyObject!) -> Void in
            NSLog("VOIP \(woot).");
        }
        
        // so, I need to design my event pipeline.  the main tricky bit is causing something to happen some delay after.  That is, I need to schedule a delay when I get something in the pipeline, BUT then I need to actually cancel that item (ie., not permit it to execute when something new comes through. it may not be possible to do that purely FRP.
        
        // Schedule a timer RACSignal as a side-effect from the subscription to the key event, and deschedule it whenever another happens? will certainly work, but basically leverages no FRP at all
        
        // make a Stream bind (proper term?) that creates and tears down a timer signal source that will emit a new event type into the pipeline (so, now it's a stream of MicrophoneCommands, namely MUTE and UNMUTE)
        
        // (keyStrokeSignal() -> NSEvent) --> (hysteresisDelay(3s) -> StateChange<true|false>) --> (microphoneSubscriber())
        
        // or, alternatively, in order to avoid implementing hysteresisDelay, which would have to be non-functional code, instead do:
        
        // keystrokes -> map to tuples of the orig keyboard event and a timeout signal -> mapFlatten -> take latest only, cancel all others -> microphone subscriber
        
        // keystrokes ->
        
        
        NSEvent.addGlobalMonitorForEventsMatchingMask(NSEventMask.KeyDownMask, { (NSEvent) -> Void in
            // poop smeeee
