genRotation q cw = do
  let (qx,qy) = center q
      xy1 = (qx-1,qy-1)
      xy2 = (qx-1,qy)
      chain1 = take 4 $ iterate (rotate_ (not cw) q) xy1
      chain2 = take 4 $ iterate (rotate_ (not cw) q) xy2
  -- putStrLn $ "cw chain1: " ++ intercalate " - " (map show chain1)
  -- putStrLn $ "cw chain2: " ++ intercalate " - " (map show chain2)
  let mask1 = foldl' setBit (0::Int64) indx1
      mask2 = foldl' setBit (0::Int64) indx2
      indx1 = map bitIndex chain1
      indx2 = map bitIndex chain2
  -- putStrLn $ printf "mask1 = 0x%010x" mask1
  -- putStrLn $ printf "mask2 = 0x%010x" mask2
  let trans1 =  intercalate " . " [ "tb v " ++ show i ++ " " ++ show j | (i,j) <- pairs indx1 ]
      trans2 =  intercalate " . " [ "tb v " ++ show i ++ " " ++ show j | (i,j) <- pairs indx2 ]
  -- putStrLn $ "trans1: " ++ trans1
  -- putStrLn $ "trans2: " ++ trans2
  let code = [ name ++ " v = maskbits (maskbits v m1 b1) m2 b2"
             , "  where"
             , "    m1 = " ++ printf "0x%010x" mask1
             , "    b1 = " ++ trans1 ++ " $ 0"
             , "    m2 = " ++ printf "0x%010x" mask2
             , "    b2 = " ++ trans2 ++ " $ 0"
             ]
      name = "rot" ++ show q ++ (if cw then "cw" else "ccw")
  putStrLn $ unlines code


genRotation q cw = do
  let (qx,qy) = center q
      xy1 = (qx-1,qy-1)
      xy2 = (qx-1,qy)
      chain1 = take 4 $ iterate (rotate_ (not cw) q) xy1
      chain2 = take 4 $ iterate (rotate_ (not cw) q) xy2
  -- putStrLn $ "cw chain1: " ++ intercalate " - " (map show chain1)
  -- putStrLn $ "cw chain2: " ++ intercalate " - " (map show chain2)
  let mask1 = foldl' setBit (0::Int64) indx1
      mask2 = foldl' setBit (0::Int64) indx2
      indx1 = map bitIndex chain1
      indx2 = map bitIndex chain2
  -- putStrLn $ printf "mask1 = 0x%010x" mask1
  -- putStrLn $ printf "mask2 = 0x%010x" mask2
  let trans1 =  intercalate " . " [ "tb v " ++ show i ++ " " ++ show j | (i,j) <- pairs indx1 ]
      trans2 =  intercalate " . " [ "tb v " ++ show i ++ " " ++ show j | (i,j) <- pairs indx2 ]
  -- putStrLn $ "trans1: " ++ trans1
  -- putStrLn $ "trans2: " ++ trans2
  let code = [ name ++ " v = maskbits (maskbits v m1 b1) m2 b2"
             , "  where"
             , "    m1 = " ++ printf "0x%010x" mask1
             , "    b1 = " ++ trans1 ++ " $ 0"
             , "    m2 = " ++ printf "0x%010x" mask2
             , "    b2 = " ++ trans2 ++ " $ 0"
             ]
      name = "rot" ++ show q ++ (if cw then "cw" else "ccw")
  putStrLn $ unlines code


genRotation q cw = do
  let (qx,qy) = center q
      xy1 = (qx-1,qy-1)
      xy2 = (qx-1,qy)
      chain1 = take 4 $ iterate (rotate_ (not cw) q) xy1
      chain2 = take 4 $ iterate (rotate_ (not cw) q) xy2
  -- putStrLn $ "cw chain1: " ++ intercalate " - " (map show chain1)
  -- putStrLn $ "cw chain2: " ++ intercalate " - " (map show chain2)
  let mask1 = foldl' setBit (0::Int64) indx1
      mask2 = foldl' setBit (0::Int64) indx2
      indx1 = map bitIndex chain1
      indx2 = map bitIndex chain2
  -- putStrLn $ printf "mask1 = 0x%010x" mask1
  -- putStrLn $ printf "mask2 = 0x%010x" mask2
  let trans1 =  intercalate " . " [ "tb v " ++ show i ++ " " ++ show j | (i,j) <- pairs indx1 ]
      trans2 =  intercalate " . " [ "tb v " ++ show i ++ " " ++ show j | (i,j) <- pairs indx2 ]
  -- putStrLn $ "trans1: " ++ trans1
  -- putStrLn $ "trans2: " ++ trans2
  let code = [ name ++ " v = maskbits (maskbits v m1 b1) m2 b2"
             , "  where"
             , "    m1 = " ++ printf "0x%010x" mask1
             , "    b1 = " ++ trans1 ++ " $ 0"
             , "    m2 = " ++ printf "0x%010x" mask2
             , "    b2 = " ++ trans2 ++ " $ 0"
             ]
      name = "rot" ++ show q ++ (if cw then "cw" else "ccw")
  putStrLn $ unlines code

