# Helper functions for Factoryman

import sys
import redis
redis_host = "localhost"
redis_port = 6379
redis_password = ""
r = redis.StrictRedis('localhost', 6379, charset="utf-8", decode_responses=True)

def workerat(gameid,x,y):
    # Returns "no" if none, otherwise returns the workerid
    workeratxy="no"
    w = 0
    while w < int(r.get(gameid+":w:count")):
      wx = int(r.get(gameid+":w:"+str(w)+":x"))
      wy = int(r.get(gameid+":w:"+str(w)+":y"))
      wactive = r.get(gameid+":w:"+str(w)+":active")
      if (wactive == "yes") and int(x)==int(wx) and int(y)==int(wy):
        workeratxy=str(w)
      w += 1
    return workeratxy

def machineat(gameid,x,y):
    machineatxy="no"
    m = 0
    while m < int(r.get(gameid+":m:count")):
      mx = int(r.get(gameid+":m:"+str(m)+":x"))
      my = int(r.get(gameid+":m:"+str(m)+":y"))
      mactive = r.get(gameid+":m:"+str(m)+":active")
      if (mactive == "yes") and int(x)==int(mx) and int(y)==int(my):
        machineatxy=str(m)
      m += 1
    return machineatxy

def cartat(gameid,x,y):
    cartatxy="no"
    c = 0
    while c < int(r.get(gameid+":c:count")):
      cx = int(r.get(gameid+":c:"+str(c)+":x"))
      cy = int(r.get(gameid+":c:"+str(c)+":y"))
      cactive = r.get(gameid+":c:"+str(c)+":active")
      if (cactive == "yes") and int(x)==int(cx) and int(y)==int(cy):
        cartatxy=str(c)
      c += 1
    return cartatxy

def addworker(gameid,x,y):
    wcount = int(r.get(gameid+":w:count"))
    r.set(gameid+":w:"+str(wcount)+":x", str(x))
    r.set(gameid+":w:"+str(wcount)+":y", str(y))
    r.set(gameid+":w:"+str(wcount)+":dx", str(x))
    r.set(gameid+":w:"+str(wcount)+":dy", str(y))
    r.set(gameid+":w:"+str(wcount)+":active", "yes")
    wcount += 1
    #errlog("WARN: wcount is "+str(wcount))
    r.set(gameid+":w:count",str(wcount))
    return

def addmachine(gameid,x,y):
    mcount = int(r.get(gameid+":m:count"))
    r.set(gameid+":m:"+str(mcount)+":x", str(x))
    r.set(gameid+":m:"+str(mcount)+":y", str(y))
    r.set(gameid+":m:"+str(mcount)+":dx", str(x))
    r.set(gameid+":m:"+str(mcount)+":dy", str(y))
    # FIXME. Later we will take as parameters; for now,
    # we hardcode every machine's input and output type.
    r.set(gameid+":m:"+str(mcount)+":input", "a2")
    r.set(gameid+":m:"+str(mcount)+":output", "b1")
    r.set(gameid+":m:"+str(mcount)+":active", "yes")
    mcount += 1
    #errlog("WARN: wcount is "+str(wcount))
    r.set(gameid+":m:count",str(mcount))
    return

def addcart(gameid,x,y):
    ccount = int(r.get(gameid+":c:count"))
    r.set(gameid+":c:"+str(ccount)+":x", str(x))
    r.set(gameid+":c:"+str(ccount)+":y", str(y))
    r.set(gameid+":c:"+str(ccount)+":dx", str(x))
    r.set(gameid+":c:"+str(ccount)+":dy", str(y))
    r.set(gameid+":c:"+str(ccount)+":active", "yes")
    r.set(gameid+":c:"+str(ccount)+":count", "0")
    r.set(gameid+":c:"+str(ccount)+":type", "none")
    ccount += 1
    r.set(gameid+":c:count",str(ccount))
    return 

def gamestatestr(gameid):
    # Return a formatted set of values representing gamestate.
    # For now, default to HTML.
    # Return worker count and list of workers x/y/active/cid/mid.
    rstr = gameid+":cash --> " + r.get(gameid+":cash") + "<br/>"
    rstr += gameid+":lastcmd --> " + r.get(gameid+":lastcmd") + "<br/>"
    rstr += gameid+":w:count --> " + r.get(gameid+":w:count") + "<br/>"
    rstr += gameid+":m:count --> " + r.get(gameid+":m:count") + "<br/>"
    rstr += gameid+":c:count --> " + r.get(gameid+":c:count") + "<br/>"
    w = 0
    while w < int(r.get(gameid+":w:count")):
       basestr = str(gameid+":w:"+str(w)+":")
       rstr += basestr+"x --> " + r.get(basestr+"x") + "<br/>"
       rstr += basestr+"y --> " + r.get(basestr+"y") + "<br/>"
       rstr += basestr+"dx --> " + r.get(basestr+"dx") + "<br/>"
       rstr += basestr+"dy --> " + r.get(basestr+"dy") + "<br/>"
       rstr += basestr+"active --> " + r.get(basestr+"active") + "<br/>"
       w += 1
    c = 0
    while c < int(r.get(gameid+":c:count")):
       basestr = str(gameid+":c:"+str(c)+":")
       rstr += basestr+"x --> " + r.get(basestr+"x") + "<br/>"
       rstr += basestr+"y --> " + r.get(basestr+"y") + "<br/>"
       rstr += basestr+"active --> " + r.get(basestr+"active") + "<br/>"
       c += 1
    m = 0
    while m < int(r.get(gameid+":m:count")):
       basestr = str(gameid+":m:"+str(m)+":")
       rstr += basestr+"x --> " + r.get(basestr+"x") + "<br/>"
       rstr += basestr+"y --> " + r.get(basestr+"y") + "<br/>"
       rstr += basestr+"active --> " + r.get(basestr+"active") + "<br/>"
       m += 1
    rstr += 'Prices: buy:A=' + r.get("buy:A") + "/"
    rstr += 'sell:A=' + r.get("sell:A") + "/"
    rstr += 'buy:B=' + r.get("buy:B") + "/"
    rstr += 'sell:B=' + r.get("sell:B") + "<br/>"
    rstr += '<form action="/command">'
    rstr += '<label for="commandid">Command:</label>'
    # rstr += 'c:<input type="text" id="c" name="c" /> '
    rstr += '<select name="c" id="c">'
    rstr += '<option value="wait">wait</option>'
    rstr += '<option value="move">move</option>'
    rstr += '<option value="buyc">buyc</option>'
    rstr += '<option value="buym">buym</option>'
    rstr += '<option value="att">attach/detach</option>'
    rstr += '</select>'
    rstr += 'v:<input type="text" id="v" name="v" />'
    rstr += '<input type="hidden" id="g" name="g" value="' + gameid + '"/>'
    rstr += '<input type="submit" value="Submit" />'
    rstr += '</form>'
    return rstr

def gamemapstr(gameid):
    # Return a formatted map representing items on the map.
    # For now, default to HTML.
    returnstr = '<pre>'                                                         
    for gmx in range(0,10):
      for gmy in range(0,10):

        # Default: empty
        mapstr="____"

        # Is there a worker? Render it
        wid=workerat(gameid,gmx,gmy)
        if wid != "no":
          mapstr="w" + str(wid) + "__"

        # Is there a machine? Render it
        mid=machineat(gameid,gmx,gmy)
        if mid != "no":
          if "w" in mapstr:
            # if w and m are attached, put m first
            if r.exists(gameid+":w:"+str(wid)+":mid"):
              mapstr="m" + str(mid) + "w" + str(wid)
            # else put w first
            else:
              mapstr="w" + str(wid) + "m" + str(mid)
          else:
            mapstr="m" + str(mid) + "__" 

        # Is there a cart ? Render it
        cid=cartat(gameid,gmx,gmy)
        if cid != "no":
          if "w" in mapstr:
            # if w and c are attached, put c first
            if r.exists(gameid+":w:"+str(wid)+":cid"):
              mapstr="c" + str(cid) + "w" + str(wid)
            # else put w first
            else:
              mapstr="w" + str(wid) + "c" + str(cid)
          else:
            mapstr="c" + str(cid) + "__" 

        # Add this tile to the map
        returnstr += mapstr + " "
      returnstr+="<br/>"
    returnstr+="<br/>"
    returnstr+="</pre>"
    return returnstr

def errlog(errstr):
    print(errstr,file=sys.stderr)
    return
