var mercury = require("mercury")


module.exports = createFrameList

// @state - snapshot of internal state
// @events - collection of internal event inputs
// @optional - argument passed into widget.thunk, not used
function frameList(state, events, optional) {
    return h("ul.frame-list", map(state.thumbnails, function (frame) {
        return h("li.frame-list-item", {
            "className": state.lastSelected === frame.id ? "highlighed" : "",
            "ex-click": mercury.event(events.frameClick, frame)
        }, [h("img", { src: frame.imageSrc })])
    }))
}

function createFrameList(state) {
    // INTERNAL VIEW STATE: turn each frame into an internal thumbnail
    // You don't need this information. This shouldn't need to leak
    // outisde of this scope. I shouldn't have to compute this externally
    // I shouldn't have to mutate global state with a new key for my purpose
    // The internal state is still readable. This is still ref transparent
    // and this is still immutable.
    var thumbnails = mercury.hash(map(state.frames, function (frame) {
        return thumbnailify(frame)
    }))
    
    var state = mercury.hash({
        thumbnails: thumbnails,
        lastSelect: null
    })
    
    // Events for consumers to listen to
    // It's nice to export a set of events that we can inspect
    // instead of injecting the listeners blindly.
    // +1 self documenting code and readability
    var publicEvents = {
        // Only onSelectFrame.output is exported on the interface
        //  mercury.io(listener<function>?) -> { 
        //      input: function(value<any>),
        //      output: function(listener<function>)
        //  }
        //   
        //    returns an event object. An event consists of two function input and output
        //       write the       read the 
        //    --> input --> O --> output -->
        //               [Event]
        //
        //  If a function is provided to mercury.io, that is the default listener to the output  
        // 
        onSelectFrame = mercury.io()
    }
    
    // Events to listen to internally on the dom
    // We probably don't want to expose this internal concern
    var internalEvents = {
        // Only frameClick.input is passed into render
        frameClick: mercury.io(function (frame) {
            // We can just write the value straight out here.
            // But we could also write to the state if we wanted
            // and allow state changes to drive the events
            publicEvents.onSelectFrame.input(frame.id)
            state.lastSelected.set(frame.id)
        })
    }

    
    return new AutonymousWidget(state, frameList, internalEvents, publicEvents)
}


function AutonymousWidget(state, render, internalEvents, publicEvents) {
    this.state = state
    this._render = render
    
    // Export the public events output only (readable/source)
    // Here we have a true notion of only being able to read this 
    // event externally
    Object.keys(publicEvents).forEach(function (eventName) {
        this[eventName] = publicEvents[eventName].output
    })
    
    var internal = this._internalEvents {}
    
    // Persist the private events listeners only (writable/sink)
    Object.keys(privateEvents).forEach(function (eventName) {
        internal[eventName] = internalEvents[eventName].input
    })
}

AnonymousWidget.prototype.partial = function (optional) {
    return mercury.partial(this._render, this.state(),
        this._internalEvents, optional)
}

@@ -27,16 +27,51 @@
 cury%22)%0A%0A
+createFrameList.Render = frameList%0A
 %0Amodule.
@@ -140,57 +140,8 @@
 ate%0A
-// @events - collection of internal event inputs%0A
 // @
@@ -224,16 +224,8 @@
 ate,
- events,
  opt
@@ -225,32 +225,72 @@
 te, optional) %7B%0A
+    var events = state._internalEvents%0A%0A
     return h(%22ul
@@ -1227,12 +1227,27 @@
 ct: 
+mercury.value(
 null
+)
 %0A   
@@ -2668,20 +2668,16 @@
  return 
-new 
 Autonymo
@@ -2682,31 +2682,19 @@
 mous
-Widget(state, frameList
+Thing(state
 , in
@@ -2748,28 +2748,19 @@
 mous
-Widget(state, render
+Thing(state
 , in
@@ -2797,52 +2797,54 @@
     
-this.state = state%0A    this._render = render
+var events = %7B%7D%0A    state._internalEvents = %7B%7D
 %0A   
@@ -3067,19 +3067,21 @@
         
-thi
+event
 s%5BeventN
@@ -3134,56 +3134,8 @@
    %0A
-    var internal = this._internalEvents %7B%7D%0A    %0A
     
@@ -3265,24 +3265,31 @@
         
+state._
 internal
 %5BeventNa
@@ -3280,16 +3280,22 @@
 internal
+Events
 %5BeventNa
@@ -3299,16 +3299,28 @@
 tName%5D =
+%0A           
  interna
@@ -3355,162 +3355,51 @@
  %7D)%0A
-%7D%0A%0AAnonymousWidget.prototype.partial = function (optional) %7B%0A    return mercury.partial(this._render, this.state(),%0A        this._internalEvents, optional)
+%0A    return %7B state: state, events: events %7D
 %0A%7D%0A

refactor frame-list to match new style