/* ******************************************************
genetics javascript (punnett.js)
by Kevin Kelleher
http://www.midlandstech.com/science/kelleherk/
copyright 2004 Kevin Kelleher. All rights reserved.
********************************************************* */

var squareColor = "#ABABAB"

function punnettSquare(pgt,mgt,da,ra,dp,rp,ip,showcross) {
		da = parseAllele(da);
		ra = parseAllele(ra);
		var patAlleles = getGametes(pgt);
		var matAlleles = getGametes(mgt);
		var pa = patAlleles[0];
		var pb = patAlleles[1];
		var ma = matAlleles[0];
		var mb = matAlleles[1];
		var cross = "";
		if (showcross == 1) {
			var ppgt = (patAlleles[0] + patAlleles[1]);
			var pmgt = (matAlleles[0] + matAlleles[1]);
			cross = ("<b>Cross:<\/b>&nbsp;&nbsp;" + ppgt + "&nbsp;&nbsp;<font class='small'>x<\/font>&nbsp;&nbsp;" + pmgt + "<br><br>");
		}
		var alleleCombos = [[pa,ma],[pa,mb],[pb,ma],[pb,mb]];
		var phenos = [];
		var genos = [];
		for (z=0;z<alleleCombos.length;z++) {
			var thePhen = rp;
			if((alleleCombos[z])[0] == da || (alleleCombos[z])[1] == da) {
				if(ip != '' && ((alleleCombos[z])[0] == ra || (alleleCombos[z])[1] == ra)) {
					thePhen = ip;
				}
				else {
					thePhen = dp;
				}
			}
			phenos[z] = thePhen;
			var theGen = ((alleleCombos[z])[0] + (alleleCombos[z])[1]);
			if ((alleleCombos[z])[0] == ra || (alleleCombos[z])[0] == 'Y') {
				theGen = ((alleleCombos[z])[1] + (alleleCombos[z])[0]);
			}
			genos[z] = theGen;
		}
		var numdom = 0;
		var numint = 0;
		for(a=0;a<phenos.length;a++) {
			if (phenos[a] == dp) numdom = (numdom+1);
			if (phenos[a] == ip) numint = (numint+1);
		}
		var percDom = (((numdom/4)*100) + '% ' + dp);
		var percRec = ((((4-(numdom+numint))/4)*100) + '% ' + rp);
		var percInt = "";
		if (ip != '' && numint != 0) percInt = ("<TR><TD>" + (((numint/4)*100) + '% ' + ip) + "<\/TD><\/TR>");
		var gendPerc = "";
		if (pa.charAt(0) == 'X' && pb == 'Y') {
			var malRec = 0;
			if (phenos[2] == rp) malRec = (malRec + 1);
			if (phenos[3] == rp) malRec = (malRec + 1);
			var femRec = 0;
			var carNote = "";
			var numCar = 0;
			if (phenos[0] == rp) femRec = (femRec + 1);
			if (phenos[1] == rp) femRec = (femRec + 1);
			if (phenos[0] == dp && genos[0].indexOf(ra) != -1) numCar = (numCar + 1);
			if (phenos[1] == dp && genos[1].indexOf(ra) != -1) numCar = (numCar + 1);
			if (numCar > 0) {
			percDom = (percDom + " *");
			carNote = ("<br><font style='font-size:13px;'>* " + ((numCar/2)*100) + "% of the female offspring will be carriers<\/font>");
}
			var gendPerc = "<TR><TD>" + ((malRec/2)*100) + "% of the male offspring will be " + rp + "<\/TD><\/TR><TR><TD>" + ((femRec/2)*100) + "% of the female offspring will be " + rp + carNote + "<\/TD><\/TR>";
		}
		var br = "<div><br><\/div>";	
		ps = cross + "<TABLE CELLPADDING='1' CELLSPACING='0' BORDER='0'><TR><TD WIDTH='20' HEIGHT='20'>&nbsp;<\/TD><TD WIDTH='75' HEIGHT='20' ALIGN='CENTER'><FONT CLASS='punnett'>" + ma + "<\/FONT><\/TD><TD WIDTH='75' HEIGHT='20' ALIGN='CENTER'><FONT CLASS='punnett'>" + mb + "<\/FONT><\/TD><TD WIDTH='20' HEIGHT='20'>&nbsp;<\/TD><TD HEIGHT='20'>&nbsp;</TD><\/TR><TR><TD ROWSPAN='2' ALIGN='CENTER' WIDTH='20'><TABLE CELLPADDING='2' CELLSPACING='0' BORDER='0' WIDTH='20' HEIGHT='120' ALIGN='CENTER'><TR><TD HEIGHT='60' ALIGN='CENTER' VALIGN='MIDDLE'><FONT CLASS='punnett'>" + br + pa + br + "<\/FONT><\/TD><\/TR><TR><TD HEIGHT='60' ALIGN='CENTER' VALIGN='MIDDLE'><FONT CLASS='punnett'>" + br + pb + br + "<\/FONT><\/TD><\/TR><\/TABLE><\/TD><TD ROWSPAN='2' COLSPAN='2' ALIGN='CENTER'><TABLE CELLPADDING='2' CELLSPACING='0' BORDER='2' BORDERCOLOR='" + squareColor + "' WIDTH='150' HEIGHT='120' CLASS='ridge;'><TR><TD WIDTH='75' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[0] + "<\/FONT><br><div>" + phenos[0] + "<\/div><\/TD><TD WIDTH='75' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[1] + "<\/FONT><br><div>" + phenos[1] + "<\/div><\/TD><\/TR><TR><TD WIDTH='75' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[2] + "<\/FONT><br><div>" + phenos[2] + "<\/div><\/TD><TD WIDTH='75' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[3] + "<\/FONT><br><div>" + phenos[3] + "<\/div><\/TD><\/TR><\/TABLE><\/TD><TD WIDTH='20'>&nbsp;<\/TD><TD ALIGN='LEFT' VALIGN='TOP' ROWSPAN='2'><TABLE CELLPADDING='0' CELLSPACING='0' BORDER='0'><TR><TD><P><u>Phenotypic Ratio:<\/u></TD></TR><TR><TD>" + percDom + "<\/TD><\/TR>" + percInt + "<TR><TD>" + percRec + "<\/TD><\/TR>" + gendPerc + "<\/TABLE><\/TD><\/TR><\/TABLE><br><br>";
		return ps;
	}
	
	function getGametes(gt) {
		var theRes = [];
		var q = 1;
		var allele = "";
		for(v=0;v<gt.length;v=(v+q)) {
			q = 1;
			allele = (gt.slice(v,(v+q)))
			if (gt.charAt(v+1) == "^") {
				allele = (gt.charAt(v) + "<sup>" + gt.charAt(v+2) + "<\/sup>");
				q = 3;
			}
			var cp =  new RegExp("c","g");
			allele = allele.replace(cp,"&copy;");
			theRes[theRes.length] = allele;
		}
		return theRes;
	}
	
	function parseAllele(al) {
		if (al.charAt(1) == "^") al = (al.charAt(0) + "<sup>" + al.charAt(2) + "<\/sup>");
		var cp =  new RegExp("c","g");
		al = al.replace(cp,"&copy;");
		return al;
	}

	function dihybridCross(pgt,mgt,daa,raa,dab,rab,dpa,rpa,dpb,rpb,showcross) {
		daa = parseAllele(daa);
		raa = parseAllele(raa);
		dab = parseAllele(dab);
		rab = parseAllele(rab);
		var patAlleles = getGametes(pgt);
		var matAlleles = getGametes(mgt);
		var cross = "";
		if (showcross == 1) {
			var ppgt = (patAlleles[0] + patAlleles[1] + patAlleles[2] + patAlleles[3]);
			var pmgt = (matAlleles[0] + matAlleles[1] + matAlleles[2] + matAlleles[3]);
			cross = ("<b>Cross:<\/b>&nbsp;&nbsp;" + ppgt + "&nbsp;&nbsp;<font class='small'>x<\/font>&nbsp;&nbsp;" + pmgt + "<br><br>");
		}
		var foilList = [[0,2],[0,3],[1,2],[1,3]];
		var phenos = [];
		var genos = [];
		var pGam = [];
		var mGam = [];
		for (y=0;y<patAlleles.length;y++) {
			var pairOne = (patAlleles[(foilList[y])[0]] + patAlleles[(foilList[y])[1]]);
			pGam[pGam.length] = pairOne;
			for (z=0;z<matAlleles.length;z++) {
				var pairTwo = (matAlleles[(foilList[z])[0]] + matAlleles[(foilList[z])[1]]);
				if (y == 0) mGam[mGam.length] = pairTwo;
				var phenOne = rpa;
				var phenTwo = rpb;
				var mod = "";
				if ((daa == "I<sup>A<\/sup>" || daa == "I<sup>B<\/sup>") && raa == "i") mod = "ABO";
				if ((dab == "I<sup>A<\/sup>" || dab == "I<sup>B<\/sup>") && rab == "i") mod = "ABO";
				if (mod == 'ABO') {
					daa = "I<sup>A<\/sup>";
					dpa = "A";
					var olddaa = "I<sup>B<\/sup>";
					var olddpa = "B";
					if (pairOne.indexOf(daa) == -1 && pairTwo.indexOf(daa) == -1) {
						olddaa = daa;
						olddpa = dpa;
						daa = "I<sup>B<\/sup>";
						dpa = "B";
					}
					if ((pairOne + pairTwo).indexOf(daa) != -1 && (pairOne + pairTwo).indexOf(olddaa) != -1) {
						dpa = "AB";
					}
				}
				if(pairOne.indexOf(daa) != -1 || pairTwo.indexOf(daa) != -1) {
					phenOne = dpa;
				}
				if(pairOne.indexOf(dab) != -1 || pairTwo.indexOf(dab) != -1) {
					phenTwo = dpb;
				}
				phenos[phenos.length] = (phenOne + "<br>" + phenTwo);
				var alleleList = [];
				var phenList = [[pairOne,daa,raa],[pairTwo,daa,raa],[pairOne,dab,rab],[pairTwo,dab,rab]];
				for(a=0;a<phenList.length;a++) {
					var theallele = '';
					var thegeno = '';
					if ((phenList[a])[0].indexOf((phenList[a])[1]) != -1) theallele = (phenList[a])[1];
					if ((phenList[a])[0].indexOf((phenList[a])[2]) != -1) theallele = (phenList[a])[2];
					if (mod == 'ABO' && theallele == '') {
						if ((phenList[a])[0].indexOf(olddaa) != -1) theallele = olddaa;
					}
					if (((phenList[a])[0].charAt(0) == 'X' || (phenList[a])[1].charAt(0) == 'X') && theallele == '') theallele = 'Y';
					if ((phenList[a])[1] == daa || (phenList[a])[2] == raa) {
						thegeno = (phenList[a])[0].slice(0,theallele.length);
					}
					else if ((phenList[a])[1] == dab || (phenList[a])[2] == rab) {
						thegeno = (phenList[a])[0].slice((phenList[a])[0].indexOf(theallele),(phenList[a])[0].length);
					}
					alleleList[a] = thegeno;
				}
				var patGen = (alleleList[0] + alleleList[1]);
				if (alleleList[0] == raa || alleleList[0] == 'Y') patGen = (alleleList[1] + alleleList[0]);
				var matGen = (alleleList[2] + alleleList[3]);
				if (alleleList[2] == rab || alleleList[3] == 'Y') matGen = (alleleList[3] + alleleList[2]);
				genos[genos.length] = (patGen + matGen);
			}
		}
		if (mod == 'ABO') {
			dpa = "B";
			olddpa = "A";
		}
		var domdom = 0;
		var domrec = 0;
		var recdom = 0;
		var recrec = 0;
		for(a=0;a<phenos.length;a++) {
			if (phenos[a] == (dpa + "<br>" + dpb)) domdom = (domdom+1);
			if (phenos[a] == (dpa + "<br>" + rpb)) domrec = (domrec+1);
			if (phenos[a] == (rpa + "<br>" + dpb)) recdom = (recdom+1);
			if (phenos[a] == (rpa + "<br>" + rpb)) recrec = (recrec+1);
		}
		var percDD = (((domdom/16)*100) + "% " + dpa + ", " + dpb);
		var percDR = (((domrec/16)*100) + "% " + dpa + ", " + rpb);
		var percRD = (((recdom/16)*100) + "% " + rpa + ", " + dpb);
		var percRR = (((recrec/16)*100) + "% " + rpa + ", " + rpb);
		var codomMod = "";
		if (mod == 'ABO') {
			var oldDomdom = 0;
			var oldDomrec = 0;
			var codomDom = 0;
			var codomRec = 0;
			for(a=0;a<phenos.length;a++) {
				if (phenos[a] == (olddpa + "<br>" + dpb)) oldDomdom = (oldDomdom+1);
				if (phenos[a] == (olddpa + "<br>" + rpb)) oldDomrec = (oldDomrec+1);
				if (phenos[a] == ("AB" + "<br>" + dpb)) codomDom = (codomDom+1);
				if (phenos[a] == ("AB" + "<br>" + rpb)) codomRec = (codomRec+1);
			}
			var percoldDD = (((oldDomdom/16)*100) + "% " + olddpa + ", " + dpb);
			var percoldDR = (((oldDomrec/16)*100) + "% " + olddpa + ", " + rpb);
			var percdDom = (((codomDom/16)*100) + "% AB, " + dpb);
			var perccdRec = (((codomRec/16)*100) + "% AB, " + rpb);
			codomMod = ("<TR><TD>" + percdDom + "<\/TD><\/TR>" + "<TR><TD>" + perccdRec + "<\/TD><\/TR>" + "<TR><TD>" + percoldDD + "<\/TD><\/TR>" + "<TR><TD>" + percoldDR + "<\/TD><\/TR>");
		}
		var br = "<div><br><\/div>";	
		ps = cross + "<TABLE CELLPADDING='1' CELLSPACING='0' BORDER='0'><TR><TD WIDTH='30' HEIGHT='20'>&nbsp;<\/TD><TD WIDTH='90' HEIGHT='20' ALIGN='CENTER'><FONT CLASS='punnett'>" + mGam[0] + "<\/FONT><\/TD><TD WIDTH='90' HEIGHT='20' ALIGN='CENTER'><FONT CLASS='punnett'>" + mGam[1] + "<\/FONT><\/TD><TD WIDTH='90' HEIGHT='20' ALIGN='CENTER'><FONT CLASS='punnett'>" + mGam[2] + "<\/FONT><\/TD><TD WIDTH='90' HEIGHT='20' ALIGN='CENTER'><FONT CLASS='punnett'>" + mGam[3] + "<\/FONT><\/TD><TD WIDTH='20' HEIGHT='20'>&nbsp;<\/TD><TD HEIGHT='20'>&nbsp;</TD><\/TR><TR><TD ROWSPAN='4' ALIGN='CENTER'><TABLE CELLPADDING='2' CELLSPACING='0' BORDER='0' WIDTH='30' HEIGHT='240' ALIGN='CENTER'><TR><TD HEIGHT='60' ALIGN='CENTER'><FONT CLASS='punnett'>" + br + pGam[0] + br + "<\/FONT><\/TD><\/TR><TR><TD HEIGHT='60' ALIGN='CENTER'><FONT CLASS='punnett'>" + br + pGam[1] + br + "<\/FONT><\/TD><\/TR><TR><TD HEIGHT='60' ALIGN='CENTER'><FONT CLASS='punnett'>" + br + pGam[2] + br + "<\/FONT><\/TD><\/TR><TR><TD HEIGHT='60' ALIGN='CENTER'><FONT CLASS='punnett'>" + br + pGam[3] + br + "<\/FONT><\/TD><\/TR><\/TABLE><\/TD><TD ROWSPAN='4' COLSPAN='4' ALIGN='CENTER'><TABLE CELLPADDING='2' CELLSPACING='0' BORDER='2' BORDERCOLOR='" + squareColor + "' WIDTH='360' HEIGHT='240' CLASS='ridge;' ALIGN='CENTER'><TR><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[0] + "<\/FONT><br><div>" + phenos[0] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[1] + "<\/FONT><br><div>" + phenos[1] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[2] + "<\/FONT><br><div>" + phenos[2] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[3] + "<\/FONT><br><div>" + phenos[3] + "<\/div><\/TD><\/TR><TR><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[4] + "<\/FONT><br><div>" + phenos[4] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[5] + "<\/FONT><br><div>" + phenos[5] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[6] + "<\/FONT><br><div>" + phenos[6] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[7] + "<\/FONT><br><div>" + phenos[7] + "<\/div><\/TD><\/TR><TR><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[8] + "<\/FONT><br><div>" + phenos[8] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[9] + "<\/FONT><br><div>" + phenos[9] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[10] + "<\/FONT><br><div>" + phenos[10] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[11] + "<\/FONT><br><div>" + phenos[11] + "<\/div><\/TD><\/TR><TR><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[12] + "<\/FONT><br><div>" + phenos[12] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[13] + "<\/FONT><br><div>" + phenos[13] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[14] + "<\/FONT><br><div>" + phenos[14] + "<\/div><\/TD><TD WIDTH='90' HEIGHT='60' ALIGN='CENTER' CLASS='cell'><FONT CLASS='punnett'>" + genos[15] + "<\/FONT><br><div>" + phenos[15] + "<\/div><\/TD><\/TR><\/TABLE><\/TD><TD WIDTH='20'>&nbsp;<\/TD><TD ALIGN='LEFT' VALIGN='TOP' ROWSPAN='4'><TABLE CELLPADDING='0' CELLSPACING='0' BORDER='0'><TR><TD><P><u>Phenotypic Ratio:<\/u></TD></TR>" + codomMod + "<TR><TD>" + percDD + "<\/TD><\/TR><TR><TD>" + percDR + "<\/TD><\/TR><TR><TD>" + percRD + "<\/TD><\/TR><TR><TD>" + percRR + "<\/TD><\/TR><\/TABLE><\/TD><\/TR><\/TABLE><br>";
		return ps;
	}