/*
 * Justice Unlimited Resistor calculator
 *
 * Copyrigh (C) 2004, Nathan (Acorn) Pooley
 *
 *
 *
 */

/*
 *
 *@DOC@ calculate resistor values
 *
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

double rval[] = {
    1.0,1.2,1.5,3.0,3.3,3.9,4.3,4.7,5.1,5.6,6.8,7.5,8.2,9.1,
    10.0,12.0,15.0,30.0,33.0,39.0,43.0,47.0,51.0,56.0,68.0,75.0,82.0,91.0,
    100.0,120.0,150.0,300.0,330.0,390.0,430.0,470.0,510.0,560.0,680.0,750.0,820.0,910.0,
    1000.0,1200.0,1500.0,3000.0,3300.0,3900.0,4300.0,4700.0,5100.0,5600.0,6800.0,7500.0,8200.0,9100.0,
    10000.0,12000.0,15000.0,30000.0,33000.0,39000.0,43000.0,47000.0,51000.0,56000.0,68000.0,75000.0,82000.0,91000.0,
    100000.0,120000.0,150000.0,300000.0,330000.0,390000.0,430000.0,470000.0,510000.0,560000.0,680000.0,750000.0,820000.0,910000.0,
};

double rtry(double target, double *best, double *best_val,
            double r1, double r2, double r3)
{
    double r;
    if (r2 && r3) {
        r = 1.0 / ((1.0 / r1) + (1.0 / r2) + (1.0 / r3));
    } else if (r2) {
        r = 1.0 / ((1.0 / r1) + (1.0 / r2));
    } else {
        r = r1;
    }

    if (r < target) return r;   // only round up

    if (best) {
        double err = target - r;
        if (err < 0.0) err = -err;
        if (err < best_val[1]) {
            best_val[0] = r;
            best_val[1] = err;
            best[0] = r1;
            best[1] = r2;
            best[2] = r3;
        }
    }

    return r;
}

void rcalc(int val, int c)
{
    int cnt = sizeof(rval)/sizeof(rval[0]);
    double best3[3] = { 1000.0, 0.0, 0.0 };
    double best3_val[2] = { 1000.0, 1000.0 };
    double best2[3] = { 1000.0, 0.0, 0.0 };
    double best2_val[2] = { 1000.0, 1000.0 };
    double best1[3] = { 1000.0, 0.0, 0.0 };
    double best1_val[2] = { 1000.0, 1000.0 };
    int i,j,k;
    double target = (double) (val);
    double r;

    if (val < 100) {
	cnt = (cnt * 2)/5;
    } else if (val < 1000) {
	cnt = (cnt * 3)/5;
    } else if (val < 1000) {
	cnt = (cnt * 4)/5;
    }

    for (i=cnt; i--; ) {
        double r1 = rval[i];
        r = rtry(target, best1, best1_val, r1, 0.0, 0.0);
        //if (r < target) break;
        for (j=cnt; j--; ) {
            double r2 = rval[j];
            r = rtry(target, best2, best2_val, r1, r2, 0.0);
            //if (r < target) break;
            for (k=cnt; k--; ) {
                double r3 = rval[k];
                r = rtry(target, best3, best3_val, r1, r2, r3);
                //if (r < target) break;
            }
        }
    }

    printf(" '%c' %2d  r=%6.2f  r1=%5.1f\n",
        c,val,best1_val[0], best1[0]);
    if (best2_val[1] < best1_val[1]) {
        printf(" '%c' %2d  r=%6.2f  r1=%5.1f  r2=%5.1f\n",
            c,val,best2_val[0], best2[0], best2[1]);
    }
    if (best3_val[1] < best1_val[1] &&
        best3_val[1] < best2_val[1]) {
        printf(" '%c' %2d  r=%6.2f  r1=%5.1f  r2=%5.1f  r3=%5.1f\n",
            c,val,best3_val[0], best3[0], best3[1], best3[2]);
    }
    printf("\n");
}

int main(int argc, char *argv[])
{
    int c;
    int num = 0;
    int isnum = 1;
    int i;

    for (i=0; i<8; i++) {
	c = getc(stdin);
	if (c == EOF) break;
    }

    printf("Content-type: text/html\n\n");
    printf("<html><body>\n");

    if (c == '=') {
        printf("<p><pre>\n");
        printf("r1, r2, and r3 in parallel are equivalent to r\n\n");
        printf("Column 1 is the character\n");
        printf("Column 2 is the target value\n");
        printf("Column 3 is the actual resistance value\n");
        printf("Column 4-6 are the resistors that make up that value\n\n");
        printf("Each character is tried 3 times - for 1, 2, and 3 resistors\n\n");
	
        while(1) {
            c = tolower(getc(stdin));
            if (c==EOF) break;
            if (isalpha(c)) {
                rcalc(c-'a'+1,c);
            } else if (isdigit(c)) {
                rcalc(c-'0'+27,c);
                rcalc(c-'0',c);
                if (isnum) {
                    isnum = 2;
                    num *= 10;
                    num += c-'0';
                }
            } else if (isspace(c) || c=='+') {
            } else {
                isnum = 0;
                printf("%c = ???\n\n",c);
            }
        }
        if (isnum == 2) {
           printf("\n\n\nTHE NUMBER %d\n",num);
    	   rcalc(num,'?');
        }
    	printf("\n\n</pre></p>\n");
    }

    printf("<p>\n");
    printf("<form action=\"resist_web\" method=\"POST\">\n");
    printf("<table>\n");
    printf("<tr><td align=RIGHT>Enter some text or a decimal number: </td><td align=LEFT><input type=TEXT name=message size=40></td></tr>\n");
    printf("<tr><td colspan=2 align=CENTER><input type=SUBMIT value=\"Submit\"></td></tr>\n");
    printf("</table>\n");
    printf("</form>\n");
    printf("</p>\n");
    
    printf("</pre></p></body></html>\n");

    return 0;
}


