'use strict'

let gen  = require('./gen.js')

module.exports = ( in1=0 ) => {
  let ugen = {
    inputs: [ in1 ],
    memory: { value: { length:1, idx: null } },
    recorder: null,

    in( v ) {
      if( gen.histories.has( v ) ){
        let memoHistory = gen.histories.get( v )
        ugen.name = memoHistory.name
        return memoHistory
      }

      let obj = {
        gen() {
          //if( typeof v === 'object' ) { console.log( 'MEMO:', gen.memo[ v.name ] ) }

          if( typeof v === 'object' && gen.memo[ this.name ] !== undefined ) {
            debugger
            return gen.memo[ this.name ]//v.name
          }else{
            let inputs = gen.getInputs( ugen )

            if( ugen.memory.value.idx === null ) {
              gen.requestMemory( ugen.memory )
              gen.memory.heap[ ugen.memory.value.idx ] = in1
            }

            let idx = ugen.memory.value.idx

            gen.addToEndBlock( 'memory[ ' + (idx*4) + '>>2 ] = fround(' +inputs[ 0 ] +')' )
            
            gen.histories.set( v, obj )

            // return ugen that is being recorded instead of ssd.
            // this effectively makes a call to ssd.record() transparent to the graph.
            // recording is triggered by prior call to gen.addToEndBlock.
            return [ this.name, inputs[ 0 ] ]
          }
        },
        name: ugen.name + '_in'+gen.getUID(),
        memory: ugen.memory
      }

      this.inputs[ 0 ] = v
      
      ugen.recorder = obj

      return obj
    },
    
    out: {
            
      gen() {
        if( ugen.memory.value.idx === null ) {
          if( gen.histories.get( ugen.inputs[0] ) === undefined ) {
            gen.histories.set( ugen.inputs[0], ugen.recorder )
          }
          gen.requestMemory( ugen.memory )
          gen.memory.heap[ ugen.memory.value.idx ] = parseFloat( in1 )
        }
        let idx = ugen.memory.value.idx
         
        return 'memory[ ' + (idx*4) + '>>2 ] '
      },
    },

    uid: gen.getUID(),
  }
  
  ugen.out.memory = ugen.memory 

  ugen.name = 'history' + ugen.uid
  ugen.out.name = ugen.name + '_out'
  ugen.in._name  = ugen.name = '_in'

  Object.defineProperty( ugen, 'value', {
    get() {
      if( this.memory.value.idx !== null ) {
        return gen.memory.heap[ this.memory.value.idx ]
      }
    },
    set( v ) {
      if( this.memory.value.idx !== null ) {
        gen.memory.heap[ this.memory.value.idx ] = v 
      }
    }
  })

  return ugen
}
