#!/usr/bin/python

# Written by Adrian Rossiter

import sys
import math

epsilon = 1e-8

def dist2_inside(v1, v2, width):
   return (v1[0]-v2[0])**2 + (v1[1]-v2[1])**2 +(v1[2]-v2[2])**2 < width+epsilon

def dist2_test(v1, v2, idx1, idx2, data=[]):
   return (v1[0]-v2[0])**2 + (v1[1]-v2[1])**2 +(v1[2]-v2[2])**2 == data[0]

#single lattices

def sc_coord_test(x, y, z): # dist2 = 1, 2, 3
   return 1

def fcc_coord_test(x, y, z): # dist2 = 2, 4, 6, 12
   return (x+y+z)%2==0

def bcc_coord_test(x, y, z): # dist2 = 3, 4, 8
   return (x%2 == y%2) and (y%2==z%2)

def rh_dodec_coord_test(x, y, z): # dist2 = 3 (8) , 
   return ( (x%2 + y%2 + z%2)==0 or
            ((x%2 + y%2 + z%2)==3 and (x/2 + y/2)%2 == (z/2)%2 ) )

def cubo_oct_coord_test(x, y, z): # dist2 = 2
   return (x%2 + y%2 + z%2)==2

def tr_oct_coord_test(x, y, z): # dist2 = 2
   return ( (z%4==0 and x%4 and y%4 and (x-y)%2) or
            (y%4==0 and z%4 and x%4 and (z-x)%2) or
            (x%4==0 and y%4 and z%4 and (y-z)%2) )

def tr_tet_tet_coord_test(x, y, z): # dist2 = 2
   return (
            ( x%2==0 and y%4 == ((x + z))%4) or
            ( y%2==0 and z%4 == ((y + x))%4) or
            ( z%2==0 and x%4 == ((z + y))%4) )

def diamond_coord_test(x, y, z): # dist2 = 3 
   return ( ((x%2+y%2+z%2)==0 and (x/2+y/2+z/2)%2==0 or
            ((x%2+y%2+z%2)==3 and (x/2+y/2+z/2)%2==0) ) )

#combo lattices


def tr_tet_tet_cubo_oct_coord_test(x, y, z): # dist2 = 4
   x=abs(x)%6; y=abs(y)%6; z=abs(z)%6;
   if(x>3):
      x=6-x
   if(y>3):
      y=6-y
   if(z>3):
      z=6-z
   dist2 = x**2 + y**2
   return ( (z%6==0 and (dist2==2 or dist2==8 )) or
            (z%6==1 and (dist2==1 or dist2==13)) or
            (z%6==2 and (dist2==4 or dist2==10)) or
            (z%6==3 and dist2==5) )
          

lat="sc"
if(len(sys.argv) > 1):
   lat = sys.argv[1]

edge_test_arg="0"
if(len(sys.argv) > 2):
   edge_test_arg = sys.argv[2]

width = 3
if(len(sys.argv) > 3):
   width = float(sys.argv[3])

iwidth = int(math.ceil(width))

trans = [0.0,0.0,0.0]
if(len(sys.argv) > 4):
   trans_str = sys.argv[4]
   try:
      trans = [float(val) for val in trans_str.split(",")]
   except:
      sys.stderr.write("error: translation is '"+trans_str+"' must be three numbers separated only by commas\n")
      sys.exit(1)


test_data=[]
coord_test = eval(lat+"_coord_test")
try:
   test_data.append(float(edge_test_arg))
   edge_test = dist2_test
except:
   edge_test = eval(edge_test_arg+"_edge_test")


verts = []
for x in range(-iwidth+int(math.floor(trans[0])), iwidth+int(math.ceil(trans[0]))+1):
   for y in range(-iwidth+int(math.floor(trans[1])), iwidth+int(math.ceil(trans[1]))+1):
      for z in range(-iwidth+int(math.floor(trans[2])), iwidth+int(math.ceil(trans[2]))+1):
         if coord_test(x, y, z) and dist2_inside((x,y,z), trans, width):
            verts.append((x, y, z))
   
edges = []
if edge_test_arg != "0":
   for i in range(len(verts)-1):
      for j in range(i+1, len(verts)):
         if edge_test(verts[i], verts[j], i, j, test_data):
            edges.append((i,j))
   
print "OFF"
print "%d %d %d" % (len(verts), len(edges), len(edges)*2)
for v in verts:
   print "%d %d %d" % (v[0], v[1], v[2])
for e in edges:
   print "2 %d %d" % (e[0], e[1])


