/*
    This file is part of lsflag.
    lsflag is a US flag generator. It generates flags conforming to the official dimensions using a specified height.
    Copyright (C) 2010  sterling pickens

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <gd.h>
#include <math.h>

struct my_stars{
	gdPoint point[5];
};

#define PI 3.14159265

void version(void){
	printf("lsflag version 0.0.1\n\n");
}

void usage(void){
	printf("Usage:\n");
	printf("flag [height as integer]\n\n"); 
}

void draw_star(gdImagePtr im, float union_h, float union_w, int white, float star_diam, float star_x_step, float star_y_step){
	float x;
	float y;
	float angle;
	float radius = star_diam / 2;
	int y_stagger = 0;
	int point_count;
	int star_count = 0;
	struct my_stars star;
	struct my_stars pent;
	gdPoint tria[3];
	gdPoint trib[3];
	gdPoint tric[3];
	gdPoint trid[3];
	gdPoint trie[3];
	int x_count;
	int y_count;
	int y_max;

	for(x_count=0; x_count<11; x_count++){
		x=x_count*star_x_step+star_x_step;
		if(y_stagger){
			y=star_y_step;
			y_max=4;
			y_stagger=0;
		}else{
			y=0;
			y_max=5;
			y_stagger=1;
		}
		for(y_count=0; y_count<y_max; y_count++){
			if(y_count==0){
				y+=star_y_step;
			}else{
				y+=star_y_step*2;
			}

			angle=-18;
			for(point_count=0; point_count<5; point_count++){
				star.point[point_count].x = x+radius*cos(angle*PI/180);
				star.point[point_count].y = y+radius*sin(angle*PI/180);
				angle+=72;
			}
			angle=18;
			for(point_count=0; point_count<5; point_count++){
				pent.point[point_count].x = x+radius/2*cos(angle*PI/180);
				pent.point[point_count].y = y+radius/2*sin(angle*PI/180);
				angle+=72;
			}
			tria[0] = pent.point[1];
			tria[1] = star.point[0];
			tria[2] = pent.point[3];

			trib[0] = pent.point[2];
			trib[1] = star.point[1];
			trib[2] = pent.point[4];

			tric[0] = pent.point[0];
			tric[1] = star.point[2];
			tric[2] = pent.point[3];

			trid[0] = pent.point[1];
			trid[1] = star.point[3];
			trid[2] = pent.point[4];

			trie[0] = pent.point[0];
			trie[1] = star.point[4];
			trie[2] = pent.point[2];

			gdImageFilledPolygon(im, tria, 3, white);
			gdImageFilledPolygon(im, trib, 3, white);
			gdImageFilledPolygon(im, tric, 3, white);
			gdImageFilledPolygon(im, trid, 3, white);
			gdImageFilledPolygon(im, trie, 3, white);
			star_count++;
		}
	}
} 


int main(int argv, char **argc){
	gdImagePtr im;
	FILE *out;

	if(argv != 2){
		version();
		printf("ERROR: Improper usage, wrong number of arguments\n");
		usage();
		exit(1);
	}
	int flag_height = atoi(argc[1]);
	if(flag_height != flag_height){
		version();
		printf("ERROR: Improper usage, non number specified\n");
		usage();
		exit(1);
	}
	if(flag_height <= 0 ){
		version();
		printf("ERROR: Improper usage, non number, 0, or negative value specified!\n");
		usage();
		exit(1);
	}
	version();

	if(atof(argc[1]) - atoi(argc[1]) !=  0 ){
		printf("Warning: you've entered %s Rounding to %d !\n", argc[1], flag_height); 
	}

	int counter1 = 0;
	int counter2 = 0;
	float stripe_bound = 0;
	//int flag_height = atoi(argc[1]);

	if(flag_height<150){
		printf("Warning: you've specified a small flag height!\n");
	}

	int flag_width = ceil( (float)1.9*(float)flag_height );
	float union_height = (float)7/(float)13*(float)flag_height;
	float union_width = (float)0.76*(float)flag_height;
	float stripe_height = (float)1/(float)13*(float)flag_height;
	float star_diam = (float)0.0616*(float)flag_height;
	float star_x_step = (float)0.063*(float)flag_height;
	float star_y_step = (float)0.054*(float)flag_height;

	printf("flag fly(height): %d\n", flag_height);
	printf("flag hoist(width): %d\n", flag_width);
	printf("union fly(height): %f\n", union_height);
	printf("union hoist(width): %f\n", union_width);
	printf("stripe height: %f\n", stripe_height);
	printf("star diameter: %f\n", star_diam);
	printf("star step x: %f\n", star_x_step);
	printf("star step y: %f\n", star_y_step);

	im = gdImageCreate(flag_width,flag_height);	

	int white = gdImageColorAllocate(im, 255, 255, 255);
	int black = gdImageColorAllocate(im, 0, 0, 0);
	int red = gdImageColorAllocate(im, 255, 0, 0);
	int blue = gdImageColorAllocate(im, 0, 0, 255);

	//union (star box)
	gdImageFilledRectangle(im, 1, 1, union_width, union_height, blue);

	//stripes
	for(counter1 = 0; counter1 < 7; counter1++){
		stripe_bound = (float)counter1*(float)stripe_height;
		if(counter2 == 0){
			gdImageFilledRectangle(im, union_width+1, stripe_bound, flag_width, stripe_bound+stripe_height, red);
		}else{
			gdImageFilledRectangle(im, union_width+1, stripe_bound, flag_width, stripe_bound+stripe_height, white);
		}
		counter2 = (counter2 ? 0 : 1);
	}
	while(counter1 < 13){
		stripe_bound = (float)counter1*(float)stripe_height;
		if(counter2 == 0){
			if(counter1 == 12){
				gdImageFilledRectangle(im, 1, stripe_bound, flag_width, flag_height, red);
			}else{
				gdImageFilledRectangle(im, 1, stripe_bound, flag_width, stripe_bound+stripe_height, red);
			}
		}else{
				gdImageFilledRectangle(im, 1, stripe_bound, flag_width, stripe_bound+stripe_height, white);
		}
		counter1++;
		counter2 = (counter2 ? 0 : 1);
	}

	//stars func
	draw_star(im, union_height, union_width, white, star_diam, star_x_step, star_y_step);

	//black line border
	gdImageLine(im, 0, 0, flag_width, 0, black);
	gdImageLine(im, 0, 0, 0, flag_height, black);
	gdImageLine(im, flag_width-1, 0, flag_width-1, flag_height, black);
	gdImageLine(im, 0, flag_height-1, flag_width, flag_height-1, black);

	out = fopen("flag.png", "w");

	gdImageInterlace(im, 1);
	gdImagePng(im, out);
	fclose(out);
	gdImageDestroy(im);

	printf("\nflag saved as flag.png\n\n");

	return 0;
}
