namespace eval taskit {} {
}

proc stdConfig::taskit {} {
  controller std "\r" 5

  obj TaskitADC rd
  prop readcmd ":0400000008.."
  prop update taskit::update
  
  kids "Taskit Settings" {
    node dig out -text
    default 00
    prop write taskit::write

    node mode out -text
    default ff
    prop write taskit::write

    node pulse out -int
    prop write taskit::pulse

    node res wr -int
    prop write taskit::writeRes
    prop read taskit::readRes

    node a0 upd
    node a1 upd
    node a2 upd
    node a3 upd
    node a4 upd
    node a5 upd
    node a6 upd
    node a7 upd

    node p upd

  }

  return "new taskit"
}

proc taskit::writeRes {} {
  sct send [format ":10000D00010200%2.2x.." [sct target]]
  return taskit::readRes
}

proc taskit::readRes {} {
  sct send ":03000D0001.."
  return taskit::updateRes
}

proc taskit::updateRes {} {
  set res 0
  scan [sct result] ":0302%4x" res
  sct update $res
  return idle
}

proc taskit::update {} {
  if {[scan [sct result] ":0410%4x%4x%4x%4x%4x%4x%4x%4x" \
      a(0) a(1) a(2) a(3) a(4) a(5) a(6) a(7)] == 8} {
    set vmax 2.5
    foreach i {0 1 2 3 4 5 6 7} {
      set a($i) [expr 2.5 * $a($i) / 65535.]
      hupdate [sct]/a$i $a($i)
    }
    hupdate [sct]/p [expr 250 * ($a(2) - 0.4) / 1.6]
    set x [expr ($a(6) - $vmax * 0.5)]
    set y [expr ($a(7) - $vmax * 0.5)]
    set r [expr abs($x) + abs($y)]
    set old [silent 0 sct old]
    if {$r < $vmax * 0.4 || $r > $vmax * 0.6} {
      error "illegal value $r  = |$x| + |$y|"
    } elseif {$y > 0} {
      if {$x > 0} {
        set ang [expr $y/$r * 90]
      } else {
        set ang [expr - $x/$r * 90 + 90]
      }
    } else {
      if {$x < 0} {    
        set ang [expr - $y/$r * 90 + 180]
      } else {
        set ang [expr $x/$r * 90 + 270]
      }
    }
    set ang [expr $ang + 360 * round(($old - $ang) / 360.0)]
    sct update $ang
    sct old $ang
  } else {
    error "bad result: [sct result]"
  }
  return idle
}

proc taskit::write {} {
  set value 0
  set mode ff
  sct update [sct target]
  scan [hvali [sct objectPath]/dig] %x value 
  scan [hvali [sct objectPath]/mode] %x mode 
  sct send [format ":10000000030600FF%4.4X%4.4X.." $mode $value]
  return taskit::completeOut
}

proc taskit::completeOut {} {
  sct update [sct target]
  return idle
}

proc taskit::pulse {} {
  scan [hvali [sct objectPath]/dig] %x value 
  scan [hvali [sct objectPath]/mode] %x mode
  set p [expr 1 << [sct target]]
  set value [expr $value & (255 - $p)]
  sct send [format ":10000000030600FF%4.4X%4.4X.." $mode $value]
  sct update [sct target]
  return taskit::pulsEnd
}

proc taskit::pulsEnd {} {
  scan [hvali [sct objectPath]/dig] %x value 
  scan [hvali [sct objectPath]/mode] %x mode
  set p [expr 1 << [sct target]]
  set value [expr $value | $p]
  sct send [format ":10000000030600FF%4.4X%4.4X.." $mode $value]
  return taskit::completeOut  
}
