/* 
*        _ _                          _ _   ____
*     __| (_)_ __ ___ __  ___ __ ___ (_) |_|___ \
*    / _` | | '_ ` _ \\ \/ / '_ ` _ \| | __| __) |
*   | (_| | | | | | | |>  <| | | | | | | |_ / __/
*    \__,_|_|_| |_| |_/_/\_\_| |_| |_|_|\__|_____|
*
*
* dimxmit2
* 
* Dimwatt pattern generator
* Copyright 2007, Bradley K. Goodman, All Rights Reserved
* http://www.bradgoodman.com/dimwatt
*/

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#include <getopt.h>
#include <net/if.h>
#include <time.h>


int checktime(void) {
	time_t thetime;
	struct tm *tmstr;

	time(&thetime);
	tmstr = localtime(&thetime);
	printf("%2.2d:%2.2d:%2.2d\n",
		tmstr->tm_hour,
		tmstr->tm_min,
		tmstr->tm_sec);

	  if (tmstr->tm_hour <16)
		return 0;
		else
		return 1;

}

unsigned char sintab[] = {
  0,   1,   1,   1,   2,   2,   2,   3,   3,   4,   5,   6,   6,   7,   8,  10,
	 11,  12,  13,  15,  16,  17,  19,  21,  22,  24,  26,  28,  30,  32,  34,  36,
	  38,  40,  43,  45,  47,  50,  52,  55,  57,  60,  63,  65,  68,  71,  74,  77,
		 79,  82,  85,  88,  91,  94,  97, 100, 103, 106, 109, 112, 116, 119, 122, 125,
		 128, 131, 134, 137, 140, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174,
		 177, 179, 182, 185, 188, 191, 193, 196, 199, 201, 204, 206, 209, 211, 213, 216,
		 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 239, 240, 241, 243, 244,
		 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255,
		 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246,
		 245, 244, 243, 241, 240, 239, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220,
		 218, 216, 213, 211, 209, 206, 204, 201, 199, 196, 193, 191, 188, 185, 182, 179,
		 177, 174, 171, 168, 165, 162, 159, 156, 153, 150, 147, 144, 140, 137, 134, 131,
		 128, 125, 122, 119, 116, 112, 109, 106, 103, 100,  97,  94,  91,  88,  85,  82,
		  79,  77,  74,  71,  68,  65,  63,  60,  57,  55,  52,  50,  47,  45,  43,  40,
			 38,  36,  34,  32,  30,  28,  26,  24,  22,  21,  19,  17,  16,  15,  13,  12,
			  11,  10,   8,   7,   6,   6,   5,   4,   3,   3,   2,   2,   2,   1,   1,   0
};

enum {
		DIR_UP=0,
		DIR_DOWN
};

enum {
		COLOR_WHITE=0,
		COLOR_RED,
		COLOR_GREEN,
		COLOR_BLUE,
		COLOR_MAX
};

#define CHAN(s,c) ((s*4)+c)
#define COLOR(c) (c%4)
#define FEATURE(c)	(c/4)

#define SECONDS 	*64

/** GLOBALS **/
#define CHAN_PER_BOARD 16
#define MAX_BOARDS 2


int sock=-1;
int sock2=-1;
int chanperboard=CHAN_PER_BOARD;
unsigned short debug=0;
unsigned int delaytime=65000;
unsigned char chan[CHAN_PER_BOARD*MAX_BOARDS];
int sendandwait() {
	int ret;
	int i;

	ret = send(sock,&chan,chanperboard,0);
	if (ret < 0) 
			perror("Send failed:");


	if (sock2 >= 0) {
		ret = send(sock2,&chan[chanperboard],chanperboard,0);
		if (ret < 0) 
				perror("Send socke2 failed:");
	}

	if (debug)  {
		for (i=0;i<16;i++)
				printf("%2.2x ",chan[i]);
		printf("\n");
	}
	usleep(delaytime);
	return 0;
}

// Pos width and Level are 0-255
void spot(int pos, int color, int level,int width) {
	int i;
	int w;
	unsigned char temp[8];
	int cp;
	int xx;
	int pp;


	for (i=0;i<sizeof(temp);i++)
		temp[i] = 0;

	cp = 127-((pos%8)*8);
	printf("POS %3d: ",pos);
	printf (" cp=%d: ",cp);
	for (w=-(2*width);w<=(2*width);w++) {
			xx = (256*w)/((width)+1);
//			printf("  xx %d cp %d xx+cp %d\n",xx,cp,xx+cp);
			xx += cp;
//			printf("cpxx %4d ",(xx));
			pp = (pos/8)+w;
			if ((pp>=0) && (pp <= sizeof(temp)) && (xx >=0) && (xx <=255)) {
				temp[pp] = sintab[xx];
				chan[(pp*4)+color] = sintab[xx];
//				printf(" pp=%d xx=%d val %d\n",(pos/8)+w,xx,sintab[xx]);
			}
//			printf("%3.3d ",temp[pos+w]);
//			printf("\n");
	}
//	printf("\n");
		

	for (i=0;i<8;i++)
			printf("%3.3d ",temp[i]);
	printf("\n");
}

void xform(void) {
		int i=0;
		for (i=0;i<sizeof(chan);i++) {
//				chan[i] = 16 - (chan[i]>>4);
				chan[i] = 13 - (chan[i]/19);
		}
}

void fadetoblack() {
	int seq;
	int i;
	for (seq=0;seq<16;seq++) {
		for (i=0;i<sizeof(chan);i++) 
				if (chan[i] >= 16)
						chan[i]-=16;
				else if (chan[i])
						chan[i]=0;
			sendandwait();
	}

}

void mixcolor(unsigned int h, unsigned s, unsigned int v,
			unsigned char *w,
			unsigned char *r,
			unsigned char *g,
			unsigned char *b
			) {

		int topval=85;
		*r=0;
		*g=0;
		*b=0;
		*w=0;
		if (h<85) {
				*r = 85-h;
				*g = h;
		} else if (h<170) {
				*g = 85-(h-85);
				*b = 85-(170-h);
		} else {
				*b = 85-(h-170);
				*r = 85-(255-h);
		}


		*r += s;
		*g += s;
		*b += s;
		*w += s;
		topval += s;
		// r+b+g = 85
		// One of these is zero
		
		*r = ((*r) * v)/topval;
		*g = ((*g) * v)/topval;
		*b = ((*b) * v)/topval;
		*w = ((*w) * v)/topval;

//		printf("%d/%d/%d is %d/%d/%d/%d\n",
//					h,s,v,*w,*r,*g,*b);
}

/**
 ** Patterns
 **/

/** Lame Twinkle **/
void pattern10() {
		int x,i,seq;
		int lastx=-1;
		int c;
		for (i=0;i<sizeof(chan);i++) 
				chan[i]=0;
		
		for (seq=0;seq< 30 SECONDS;seq++) {
				for (i=0;i<sizeof(chan);i++)
					if (chan[i]>8)
						chan[i]-=8;
					else
						chan[i]=0;
			for (i=0;i<7;i++) {
				
				c = rand()%4;
					chan[(i*4)+c]=255;
			}
				
				xform();
				if (sendandwait())
						return;
//				chan[x*4]=0;
				lastx=x;

		}
}
/** Popcorn **/
void pattern9() {
		int x,i,seq;
		int lastx=-1;
		int c;
		for (i=0;i<sizeof(chan);i++) 
				chan[i]=0;
		
		for (seq=0;seq< 20 SECONDS;seq++) {
				for (i=0;i<sizeof(chan);i++)
					if (chan[i]>20)
						chan[i]-=20;
					else
						chan[i]=0;
				
				c = rand()%4;
				if ((seq%4)==0) {
					while (x==lastx)
						x=(x+((rand()%2))+4)%8;
					chan[(x*4)+c]=255;
				}
					xform();
				if (sendandwait())
						return;
//				chan[x*4]=0;
				lastx=x;

		}
}

/** Left to right pulse with colorshift **/
void pattern8() {
	int x;
	int seq;
	int f=0;
	int dir=DIR_UP;;
	int color=0;
	int xlate;
	int yy;
	unsigned char c1,c2,c3,c4;

	c1=0;
	c2=0;
	c3=0;
	c4=0;
		for (seq=0;seq< 20 SECONDS;seq++) {
			int pos;
			
			if ((seq%14)<7)
					pos = (seq%14);
			else
					pos = 7-((seq%14)-7);
//			printf ("%d %d\n",seq,pos);
			for (x=0;x<8;x++)  {
							if (pos == x) {
								
		mixcolor((seq*7)%256,30,255,&c1,&c2,&c3,&c4);
								chan[(x*4)] =c1;
								chan[(x*4)+1] =c2;
								chan[(x*4)+2] =c3;
								chan[(x*4)+3] =c4;
							} else if ((pos == x-1) || (pos == x+1)) {
								chan[(x*4)] =c1/2;
								chan[(x*4)+1] =c2/2;
								chan[(x*4)+2] =c3/2;
								chan[(x*4)+3] =c4/2;
							} else {
								chan[(x*4)] =0;
								chan[(x*4)+1] =0;
								chan[(x*4)+2] =0;
								chan[(x*4)+3] =0;
							}
			}

				xform();
				if (sendandwait())
						return;
		}
	
}
/** Left to right pulse with colorshift **/
void pattern7() {
	int i;
	int x;
	int seq;
	int f=0;
	int dir=DIR_UP;;
	int color=0;
	int xlate;
	int clate;
	int c;
	unsigned char c1,c2,c3,c4;

	for (seq=0;seq<20 SECONDS;seq++) {
		for (x=0;x<8;x++) {
			mixcolor((seq*7)%256,0,sintab[((seq-x)*28)%256],&c1,&c2,&c3,&c4);
						chan[CHAN(x,0)] = c1;
						chan[CHAN(x,1)] = c2;
						chan[CHAN(x,2)] = c3;
						chan[CHAN(x,3)] = c4;
	
		}
		xform();
			if (sendandwait())
					return;

				
		
	}
}

/* Left to right stacking */
void pattern6() {
	int seq;
	int i,x,y,c;
	int fromc,toc;

	fromc=-1;
	toc = rand()%COLOR_MAX;
	for (i=0;i<sizeof(chan);i++)
		chan[i]=0;

	for (seq=0;seq<16;seq+=4) {
		for (i=7;i>0;i--) {
			for (x=0;x<=i;x++) {
				for (y=0;y<=7;y++) {
					for (c=0;c<4;c++) {
							if ((x==y) && (c==toc))
									chan[CHAN(y,c)] =  255;
							else if ((y<=i) && (c==fromc))
									chan[CHAN(y,c)]=255;
							else if ((y>i) && (c==toc))
									chan[CHAN(y,c)]=255;
							else 
									chan[CHAN(y,c)]=0;
					}
					}
				xform();
			if (sendandwait())
				return;
			}
		}
			fromc=toc;
			toc = (toc+1)%4;

	}
}

/** Slow shifting color bands **/
void pattern5() {
	int i;
	int seq;
	int f=0;
	int dir=DIR_UP;;
	int color=0;
	int xlate;

	for (seq=0;seq<20 SECONDS;seq+=4) {
		for (i=0;i<sizeof(chan);i++)  {
						xlate=((FEATURE(i)*32)+seq+(COLOR(i)*128))%512;
						if (xlate >=256)
								chan[i]=0;
						else
						chan[i]=sintab[xlate];
		}

		xform();
			if (sendandwait())
					return;
	}
}



/* Single Feature Walk left-right-left - change color */
void pattern4() {
	int i;
	int seq;
	int f=0;
	int dir=DIR_UP;;
	int color=0;

	for (seq=0;seq<20 SECONDS;seq++) {
		for (i=0;i<sizeof(chan);i++) {
				if ((f==FEATURE(i)) && (color==COLOR(i)))
					chan[i]=255;
				else
					chan[i]=0;
		}
		xform();
			if (sendandwait())
					return;
			if (dir==DIR_UP) {
					if (f < 7)
						f++;
					else {
						dir = DIR_DOWN;
						f--;
					}
			} else {
				if (f > 0) {
						f--;
				} else {
						dir = DIR_UP;
						color = (color+1)%4;
				}
			}
	}
}

/* Twinkle - ( Needs to be double-speed to look ok) */

void pattern3() {
	int i;
	int seq;
	int ch=0;
	int color=0;

	for (seq=0;seq<20 SECONDS;seq++) {
		for (i=0;i<sizeof(chan);i+=4) {
			ch=rand()%4;
				chan[i+ch]=128;
		}
		xform();
			if (sendandwait())
					return;
	for (i=0;i<sizeof(chan);i++)
				chan[i]=255;
	xform();
			if (sendandwait())
					return;
	}
}


/* Multicolor Crossfade */
void pattern2() {
	int i;
	int color=COLOR_WHITE;
	int seq;
	int level=0;
	int dir=DIR_UP;
	for (i=0;i<sizeof(chan);i++)
				chan[i]=0;

	for (seq=0;seq<20 SECONDS;seq++) {
			
			for (i=0;i<sizeof(chan);i++) {
				if (COLOR(i) == (color+FEATURE(i))%4) {
						chan[i] = level;
				} else {
						if (chan[i])
							chan[i] -=16;
				}
			}

		if (level > 13) {
					color = (color+1) % 4;
					level=13;
		} else {
				level+=1;
		}
#if 0
			if (dir == DIR_UP ) {
				if (level >192) 
					dir = DIR_DOWN;
				else
					level+=16;
			} else {
				if (level == 0)  {
					dir = DIR_UP;
					color = (color+1) % 4;
				} else
					level-=16;
			}
#endif

			xform();
			if (sendandwait())
					return;
	}
}

// two-way intermittant step cross-fade

void pattern11() {
	short color1=rand()%4;
	short color2=rand()%4;
	int f,c,p,i;

	do {
	color1=rand()%4;
	color2=rand()%4;
	} while (color1==color2);

	for (i=0;i<sizeof(chan);i++)
		chan[i]=13;
	for (i=0;i<10;i++) {
		for (p=0;p<=13;p++) {
			if ((p==8) || (p==6) || (p==7))
				continue;
			for (f=0;f<8;f++) {
					if ((f+i)%2) {
						chan[(f*4)+color1] = p;
						chan[(f*4)+color2] = 13-p;
					} else {
						chan[(f*4)+color1] = 13-p;
						chan[(f*4)+color2] = p;
					}
			}
	sendandwait();
		}
	sleep(2);
	}
}

// four-way intermittant step cross-fade

void pattern12() {

	int i,p,f,c;
	for (i=0;i<sizeof(chan);i++)
		chan[i]=13;
	for (i=0;i<16;i++) {
		for (p=0;p<=13;p++) {
			if ((p==8) || (p==6) || (p==7))
				continue;
			for (f=0;f<8;f++) {
					for (c=0;c<4;c++) {
						if (c== ((f+i)%4))
							chan[(f*4)+c] = p;
						else if (c== ((f+i+1)%4))
							chan[(f*4)+c] = 13-p;
						else
							chan[(f*4)+c] = 13;
				}
			}
	sendandwait();
		}
	sleep(2);
	}
}

void pattern13() {

		int pos[4];
		int speed[4];
		int dir[4];
		int i;
		int c;
		int s;
		int rpos;

		for (i=0;i<4;i++) {
				pos[i]=0;
				speed[i]=(i*3)+2;
				dir[i]=0;
		}
				

		for (i=0;i<20 SECONDS;i++) {
				for (c=0;c<sizeof(chan);c++)
						chan[c]=14;
				for (c=0;c<4;c++) {
					s = speed[c];
					if (!(i % s)) {
						if (dir[c]) {
							pos[c]++;
							if (pos[c] >= 16) {
									pos[c]=15;
									dir[c]=0;
							}
							
						} else {
							pos[c]--;
							if (pos[c] <= 0) {
									pos[c]=0;
									dir[c]=1;
							}
						}
					}

						rpos = pos[c]/2;
						if (pos[c]%2) {
							if ((rpos >=0) && (rpos <=7)) chan[((rpos*4)+c)] = 0;
							rpos+=1;
							if ((rpos >=0) && (rpos <=7)) chan[((rpos*4)+c)] = 10;
							rpos-=2;
							if ((rpos >=0) && (rpos <=7)) chan[((rpos*4)+c)] = 10;
						} else {
							rpos-=1;
							if ((rpos >=0) && (rpos <=7)) chan[((rpos*4)+c)] = 3;
							rpos+=1;
							if ((rpos >=0) && (rpos <=7)) chan[((rpos*4)+c)] = 3;
							chan[((rpos*4)+c)] = 6;
						}
				}
				sendandwait();
		}
}

void pattern34() {
		int x,c,l,y;
		int f;
		for (x=0;x<8;x++) {
			for (c=0;c<4;c++)  {
				for (l=13;l>=0;l--) {
						if ((l==6) || (l==7))
							continue;
						for (y=0;y<4;y++) {
								if (y==c) {
										for (f=0;f<8;f++) 
											chan[y+(f*4)] = l;
										
								}
								else {
										for (f=0;f<8;f++) 
											chan[y+(f*4)] = 13;
								}
						}
			if (sendandwait())
					return;
				}
				for (l=0;l<13;l++) {
						if ((l==6) || (l==7))
							continue;
						for (y=0;y<4;y++) {
								if (y==c) {
										for (f=0;f<8;f++) 
											chan[y+(f*4)] = l;
								}
								else {
										for (f=0;f<8;f++) 
											chan[y+(f*4)] = 13;
								}
						}
						
			if (sendandwait())
					return;
				}
			}
		}
}

void pattern1() {
	int i;
	int seq;
	for (seq=0;seq<20 SECONDS;seq++) {
			
			for (i=0;i<sizeof(chan);i++)
				chan[i]=((i+seq)*3)%14;

			if (sendandwait())
					return;
	}
}

/** Left to right pulse with colorshift **/
void pattern14() {
	int i;
	int x;
	int seq;
	int f=0;
	int dir=DIR_UP;;
	int color=0;
	int xlate;
	int clate;
	int c;
	unsigned char c1,c2,c3,c4;
	int phase;
	int pnum=0;

	for (seq=0;seq<20 SECONDS;seq++) {
			pnum = sintab[(seq)%256]/16;
			pnum += sintab[(seq*3)%256]/9;
		for (x=0;x<8;x++) {
			phase = sintab[((pnum+x)*8)%256];
			mixcolor(phase,0,255,&c1,&c2,&c3,&c4);
						chan[CHAN(x,0)] = c1;
						chan[CHAN(x,1)] = c2;
						chan[CHAN(x,2)] = c3;
						chan[CHAN(x,3)] = c4;
	
		}
		xform();
			if (sendandwait())
					return;
	}
}

void pattern15() {
	int i,x;
	int c;
	int phase=0;
	int pos[4];
	int p;

	for (c=0;c<4;c++)
		pos[c]=0;

	for (i=0;i<20 SECONDS;i++) {
		for (x=0;x<sizeof(chan);x++)
			chan[x]=13;
		for (c=0;c<4;c++) {
			p = (phase - (c*4))%12;
			if (p==0) {
				pos[c] = rand()%8;
			}
			chan[(pos[c]*4)+c] = p;
			if (pos[c]-1 >= 0)
				chan[((pos[c]-1)*4)+c] = (p+8);
			if (pos[c]+1 <= 7)
				chan[((pos[c]+1)*4)+c] = (p+8);
		}
		if (sendandwait())
			return;
			phase++;
	}
}

void pattern16() {
	int i;
	int x;
	int seq;
	int f=0;
	int dir=DIR_UP;;
	int color=0;
	int xlate;
	int clate;
	int c;
	unsigned char c1,c2,c3,c4;
	int phase;
	int pnum=0;

	for (seq=0;seq<20 SECONDS;seq++) {
		for (c=0;c<sizeof(chan);c++)
			chan[c] = 14;
		for (c=0;c<4;c++) {
			for (x=0;x<8;x++) {
				phase = sintab[(((seq+(c*30))*3)+x)%256];
							chan[CHAN(x,c)] = phase;
			}
		}
		xform();
			if (sendandwait())
					return;
	}
}
void pattern17() {
	int i;
	int x;
	int seq;
	int f=0;
	int dir[4];;
	int color=0;
	int xlate;
	int clate;
	int c;
	unsigned char c1,c2,c3,c4;
	int phase[4];
	int pnum=0;

	for (c=0;c<4;c++) {
		phase[c] = c*200;
		dir[c] = c&1;
	}
	for (seq=0;seq<20 SECONDS;seq++) {
		for (c=0;c<sizeof(chan);c++)
			chan[c] = 14;
		for (c=0;c<4;c++) {
			phase[c] += 16+c;
			for (x=0;x<8;x++) {
				pnum = 450-(phase[c]%800);
				//pnum += ((pnum+(c*200)) % 800);
				if (dir[c])
					pnum += (x*32);
					else
					pnum -= (x*32);
				if ((pnum >=0) && ((pnum) <= 255)) {
					chan[CHAN(x,c)] = sintab[pnum%256];
				}
			}
		}
		xform();
			if (sendandwait())
					return;
	}
}
typedef void (* patternfunc_t) (void);
patternfunc_t patterns[] = {
// 	&pattern1,
//	&pattern2,
// 	&pattern3,
 &pattern34,
	&pattern4,
	&pattern5,
	&pattern6,
	&pattern7,
	&pattern8,
	&pattern11,
	&pattern12,
	&pattern13,
	&pattern14,
	&pattern15,
	&pattern16,
	&pattern17,
	0L
};

void alloff(void) {
	int i;
	for (i=0;i<sizeof(chan);i++) {
		chan[i]=14;
	}
	sendandwait();
}
extern char *optarg;
extern int optint;
int single=-1;
void randpatterns() {
		do {
			int x;
			if (checktime()) {
				x = rand()%((sizeof(patterns)/sizeof(void *))-1);
				printf("Pattern %d\n",x);
				patterns[x]();
			} else {
				printf("Sleeping\n");
				alloff();
				sleep(60);
			}
		} while(1);
}

void ident() {
	int sendsize;
	int i,x,z;
	for (i=0;i<sizeof(chan);i++)
			chan[i] = 14;
			
	sendandwait();
	sleep(3);
			

	while(1) {
	for (x=0;x<sizeof(chan);x++) {
		for (z=1;z<=x+1;z++) {
			chan[x]=0;
			sendandwait();
			usleep(125000);
			chan[x]=14;
			sendandwait();
			usleep(125000);
		}
		sleep(1);
	}
	}
}

enum {
		CMD_NONE=0,
		CMD_IDENT
};

void print_usage(void) {
		printf("USAGE: dimxmit2 [options] [levels...]\n");
		printf("Options:\n");
		printf("  -c {pattern} - Run pattern only\n");
		printf("  -a {address} - Primary IP Address\n");
		printf("  -A {address} - Secondary IP Address\n");
		printf("  -p {port} - Primary IP Port\n");
		printf("  -P {port} - Secondary IP Port\n");
		printf("  -d {delay} - Delay time (usecs)\n");
		printf("  -s {channel} - Turn on only channel\n");
		printf("  -n {channels} - Number of channels per board (default=16)\n");
		printf("  -D - Debug output\n");
		printf("  -x - Turn lights off\n");
		printf("  -e {level} - Set every channel to level\n");

}

int main(int argc,char **argv){
struct sockaddr_in addr_ip;
struct in_addr in_addr;
unsigned int seq=0;
char *addrstr="127.0.0.1";
char *addrstr2=0L;
int port1=1234;
int port2=1234;
int opt;
int pattern=-1;
int every=-1;
int ret;
int cmd = CMD_NONE;
int turnoff=0;

while ((opt = getopt(argc,argv,"e:xn:Dia:s:d:A:p:P:c:"))>0) {
		switch (opt) {
				case 'x':
						turnoff=1;
				break;
				case 'e':
						every = strtoul(optarg,0L,0);
				break;
				case 'c':
						pattern = strtoul(optarg,0L,0);
				break;
				case 'D':
						debug++;
				break;
				case 's':
						single = strtoul(optarg,0L,0);
						printf("Single is %d\n",single);
				break;
				case 'd':
						delaytime = strtoul(optarg,0L,0);
				break;
				case 'a':
						addrstr=optarg;
				break;
				case 'A':
						addrstr2=optarg;
				break;
				case 'p':
						port1=strtoul(optarg,0L,0);
				break;
				case 'P':
						port2=strtoul(optarg,0L,0);
				break;
				case 'i':
						cmd=CMD_IDENT;
				break;
				case 'n':
						chanperboard=strtoul(optarg,0L,0);
				break;
				case '?':
						print_usage();
						return 1;
				break;
		}
}


sock = socket(PF_INET,SOCK_DGRAM,0);
if (sock < 0) {
		perror("Couldn't open socket:");
}


if (addrstr2) {
	sock2 = socket(PF_INET,SOCK_DGRAM,0);
	if (sock2 < 0) {
			perror("Couldn't open socket2:");
	}
}





printf("socket: %s\n",addrstr,port1);
if (sock2 >= 0)
	printf("socket2: %s %d\n",addrstr,port2);


addr_ip.sin_family = AF_INET;
inet_aton(addrstr,&in_addr);
addr_ip.sin_addr.s_addr = in_addr.s_addr = in_addr.s_addr;
addr_ip.sin_port = htons(port1);
if (connect(sock,(struct sockaddr *)&addr_ip,sizeof(addr_ip)) == -1) {
		perror("Couldn't connect socket:");
		exit( 1);
}

if (sock2 >= 0) {
	addr_ip.sin_family = AF_INET;
	inet_aton(addrstr2,&in_addr);
	addr_ip.sin_addr.s_addr = in_addr.s_addr = in_addr.s_addr;
	addr_ip.sin_port = htons(port2);
	if (connect(sock2,(struct sockaddr *)&addr_ip,sizeof(addr_ip)) == -1) {
			perror("Couldn't connect socket2:");
			exit( 1);
	}
}

tcdrain(1);
printf("Started at ");
checktime();
printf("%d channels per board\n",chanperboard);

if (cmd == CMD_IDENT)
		ident();
if (single >= 0) {
	printf("Single: %d\n",single);
	int i;
	for (i=0;i<sizeof(chan);i++) 
			chan[i]=14;
	chan[single] = 0;
	sendandwait();
	return 0;
}

if (every >= 0) {
	printf("Every: %d\n",every);
	int i;
	for (i=0;i<sizeof(chan);i++) 
			chan[i]=every;
	sendandwait();
	return 0;
}
printf ("argc: %d optind %d\n",argc,optind);
if (optind  < argc) {
	int sendsize;
	int i,ret;
	for (sendsize=0;optind < argc;sendsize++) 
			chan[sendsize] = strtoul(argv[optind++],0L,0);
	sendandwait();
	return 0;
}

if (turnoff) {
	alloff();
	return 0;
}

if (pattern == -1)
	randpatterns();
else
			patterns[pattern]();

//fadetoblack();
close(sock);
}

