/* Simulation copyright (c) 2009 Reed A. Cartwright, PhD <reed@scit.us>
 *   Contains  a binomial RNG copyright (C) 1996-2003 James Theiler, Brian Gough
 *   http://www.gnu.org/licenses/gpl-2.0.html
 *   Ported from gsl/randist/binomial_tpe.c by Dan Earle <danearle@orielsystems.com>
 */
(function(a){a.widget("ui.redlynx",{histcolors:["#FF0000","#FF8000","#FFFF00","#80FF00","#00FF00","#00FF80","#00FFFF","#0080FF","#0000FF","#8000FF","#FF00FF","#FF0080",],histpos:0,ylabs:["0.0","","0.1","","0.2","","0.0","","0.1","","0.2","","0.0","","0.1","","0.2","","0.0","","0.1","","0.2","","0.0","","0.1","","0.2","","0.0","","0.1","","0.2","","0.0","","0.1","","0.2","",],_setID:function(b){var c=this.options.idPrefix+a.data(b);b.attr("id",c);return c},_init:function(){var c=this;this.$canvus=a('<div class="canvus"/>');this.$warn=a('<div class="ui-widget"><div class="ui-state-error ui-corner-all"><p><span class="ui-icon ui-icon-alert"></span><strong>Error:</strong> Your browser does not support SVG.  Try Firefox.</p></div></div>');this.element.addClass("ui-redlynx").append(this.$canvus).append(this.$warn);this.$canvus.svg({initPath:this.options.initPath,onLoad:function(f){c.$svg=f;c.$warn.hide();f.graph.noDraw().title("Frequency of Allele A");f.graph.yAxis.title("Percentage in Population").scale(-5,105).ticks(10,5);f.graph.xAxis.title("Generation").scale(0,2000).ticks(2000/4,2000/16);f.graph.legend.show(0);f.graph.noDraw().chartArea([0.1,0.1,0.95,0.85]).chartType("line").redraw()}});this.$control=a('<div class="control ui-widget"/>');var d,b;d=a('<p class="ui-helper-clearfix ui-redlynx-buttons"/>');var e=a('<a href="#" class="ui-redlynx-run ui-state-default ui-corner-all"><span class="ui-icon ui-icon-refresh"></span>Run Simulation</a>').click(function(f,g){f.preventDefault();c.element.redlynx("simulate")}).hover(function(f,g){a(this).addClass("ui-state-hover")},function(f,g){a(this).removeClass("ui-state-hover")}).mousedown(function(f,g){a(this).addClass("ui-state-active")}).mouseup(function(f,g){a(this).removeClass("ui-state-active")});d.append(e);var e=a('<a href="#" class="ui-redlynx-clear ui-state-default ui-corner-all"><span class="ui-icon ui-icon-trash"></span>Clear Graph</a>').click(function(f,g){f.preventDefault();c.element.redlynx("clear_graph")}).hover(function(f,g){a(this).addClass("ui-state-hover")},function(f,g){a(this).removeClass("ui-state-hover")}).mousedown(function(f,g){a(this).addClass("ui-state-active")}).mouseup(function(f,g){a(this).removeClass("ui-state-active")});d.append(e);this.$control.append(d);d=a('<p class="ui-helper-clearfix"/>');this.$control.$size=a('<input type="text" value="800" size="6"/>');b=a("<div/>").slider({min:1000,max:5000,step:1,range:"min",orientation:"horizontal",value:2903,slide:function(f,g){c.$control.$size.val(Math.round(Math.pow(10,g.value/1000)));c.$control.$start.val(Math.round((c.$control.$start_freq.slider("value")/10000)*2*c.$control.$size.val()))}});d.append('<label for="'+this._setID(this.$control.$size)+'" title="Diploid Population Size">Population Size:</label>').append(b).append(this.$control.$size);this.$control.append(d);d=a('<p class="ui-helper-clearfix"/>');this.$control.$start=a('<input type="text" value="800" size="6"/>');b=a("<div/>").slider({min:0,max:10000,step:1,range:"min",orientation:"horizontal",value:5000,slide:function(f,g){c.$control.$start.val(Math.round((g.value/10000)*2*c.$control.$size.val()))}});this.$control.$start_freq=b;d.append('<label for="'+this._setID(this.$control.$start)+'" title="Allele A is graphed.">Num of Allele A:</label>').append(b).append(this.$control.$start);this.$control.append(d);d=a('<p class="ui-helper-clearfix"/>');this.$control.$sel=a('<input type="text" value="1" size="8"/>');b=a("<div/>").slider({min:-200,max:200,step:1,range:"min",orientation:"horizontal",value:0,slide:function(g,i){var h=Math.pow(i.value/200,3);h=Math.pow(10,h).toString().match(/^\d{1,3}(.\d\d\d\d)?/)[0];c.$control.$sel.val(h)}});d.append('<label for="'+this._setID(this.$control.$sel)+'" title="Homozygote aa always has a fitness of 1.">Fitness of AA (1+s):</label>').append(b).append(this.$control.$sel);this.$control.append(d);d=a('<p class="ui-helper-clearfix"/>');this.$control.$dom=a('<input type="text" value="0.5" size="8"/>');b=a("<div/>").slider({min:-200,max:400,step:1,range:"min",orientation:"horizontal",value:100,slide:function(f,g){c.$control.$dom.val(g.value/200)}});d.append('<label for="'+this._setID(this.$control.$dom)+'" title="Aa\'s fitness is 1+hs." >Dominance (h):</label>').append(b).append(this.$control.$dom);this.$control.append(d);d=a('<p class="ui-helper-clearfix"/>');this.$control.$fmut=a('<input type="text" value="0" size="8"/>');b=a("<div/>").slider({min:0,max:10000,step:1,range:"min",orientation:"horizontal",value:0,slide:function(g,i){if(i.value==0){c.$control.$fmut.val("0")}else{if(i.value>=8000){var j=(i.value/1000)-10;var h=Math.pow(10,j).toString().match(/^\d(.\d\d\d\d)?/)[0];c.$control.$fmut.val(h)}else{var j=(i.value/1000)-10;var k=Math.floor(j);var h=Math.pow(10,j-k).toString().match(/^\d(.\d\d\d)?/)[0];c.$control.$fmut.val(h+"e"+k)}}}});d.append('<label for="'+this._setID(this.$control.$fmut)+'" title="Probability of a->A mutation.">&mu; Forward:</label>').append(b).append(this.$control.$fmut);this.$control.append(d);d=a('<p class="ui-helper-clearfix"/>');this.$control.$bmut=a('<input type="text" value="0" size="8"/>');b=a("<div/>").slider({min:0,max:10000,step:1,range:"min",orientation:"horizontal",value:0,slide:function(g,i){if(i.value==0){c.$control.$bmut.val("0")}else{if(i.value>=8000){var j=(i.value/1000)-10;var h=Math.pow(10,j).toString().match(/^\d(.\d\d\d\d)?/)[0];c.$control.$bmut.val(h)}else{var j=(i.value/1000)-10;var k=Math.floor(j);var h=Math.pow(10,j-k).toString().match(/^\d(.\d\d\d)?/)[0];c.$control.$bmut.val(h+"e"+k)}}}});d.append('<label for="'+this._setID(this.$control.$bmut)+'" title="Probability of A->a mutation.">&mu; Backward:</label>').append(b).append(this.$control.$bmut);this.$control.append(d);d=a('<p class="ui-helper-clearfix"/>');this.$control.$gens=a('<input type="text" value="2000" size="6"/>');b=a("<div/>").slider({min:5,max:10000,step:5,range:"min",orientation:"horizontal",value:this.$control.$gens.val(),slide:function(f,g){c.$control.$gens.val(g.value)}});d.append('<label for="'+this._setID(this.$control.$gens)+'" title="How long to run the simulation.">Generations:</label>').append(b).append(this.$control.$gens);this.$control.append(d);this.element.append(this.$control)},simulate:function(){var j=parseInt(this.$control.$gens.val());var d=parseInt(this.$control.$size.val());var s=parseInt(this.$control.$start.val());var x=parseFloat(this.$control.$fmut.val());var t=parseFloat(this.$control.$bmut.val());var o=parseFloat(this.$control.$sel.val());var f=parseFloat(this.$control.$dom.val());var l=[];l.push(100*s/(2*d));for(var e=1;e<=j;e+=1){var c=(s*(1-t)+((2*d)-s)*x)/(2*d);var b=1-c;var k=Math.max(1-f+f*o,0);var r=c*o+b*k;var m=c*k+b;c=c*r/(c*r+b*m);s=this.binom.get(c,2*d);l.push(100*s/(2*d))}this.addHistory(l)},addHistory:function(e){if(this.histpos==this.histcolors.length){this.histpos=0;this.$svg.graph._series=[]}var b=this.histcolors[this.histpos++];var c=this.$svg.graph.noDraw().xAxis.scale();if(c.max!=e.length){var d=e.length-1;this.$svg.graph.xAxis.scale(0,d).ticks(d/4,d/16)}this.$svg.graph.addSeries("",e,b,b,2).redraw()},clear_graph:function(){this.histpos=0;this.$svg.graph._series=[];this.$svg.graph.redraw()},binom:{SMALL_MEAN:14,BINV_CUTOFF:110,FAR_FROM_MEAN:20,Stirling:function(d){var b=d*d;var c=(13860-(462-(132-(99-140/b)/b)/b)/b)/d/166320;return c},get:function(M,P){var r;var l=0;var L,K,X;if(P==0){return 0}if(M>0.5){M=1-M;l=1}L=1-M;K=M/L;X=P*M;if(X<this.SMALL_MEAN){var j=Math.pow(L,P);while(1){var W=j;var J=Math.random();for(r=0;r<=this.BINV_CUTOFF;++r){if(J<W){break}J-=W;W*=K*(P-r)/(r+1)}if(J<W){break}}}else{var R;var H=X+M;var Q=Math.floor(H);var w=Q;var D=w+0.5;var t=X*L;var Z=Math.floor(2.195*Math.sqrt(t)-4.6*L)+0.5;var E=D-Z;var A=D+Z;var aa=0.134+20.5/(15.3+w);var Y=Z*(1+aa+aa);var h=(H-E)/(H-E*M);var N=h*(1+0.5*h);var b=(A-H)/(A*L);var G=b*(1+0.5*b);var V=Y+aa/N;var T=V+aa/G;var y,d;var J,I;while(1){J=Math.random()*T;I=Math.random();if(J<=Z){r=Math.floor(D-Z*I+J);break}else{if(J<=Y){var F=E+(J-Z)/aa;I=I*aa+1-Math.abs(F-D)/Z;if(I>1||I<=0){continue}r=Math.floor(F)}else{if(J<=V){r=Math.floor(E+Math.log(I)/N);if(r<0){continue}I*=((J-Y)*N)}else{r=Math.floor(A-Math.log(I)/G);if(r>P){continue}I*=((J-V)*G)}}}R=Math.abs(r-Q);if(R<=this.FAR_FROM_MEAN){var U=(P+1)*K;var W=1;y=I;if(Q<r){var S;for(S=Q+1;S<=r;S++){W*=(U/S-K)}}else{if(Q>r){var S;for(S=r+1;S<=Q;S++){W/=(U/S-K)}}}d=W}else{y=Math.log(I);if(R<t/2-1){var z=R/t*((R*(R/3+0.625)+(1/6))/t+0.5);var O=-(R*R/(2*t));if(y<O-z){break}if(y>O+z){continue}}var o=r+1;var B=P-r+1;var e=w+1;var C=P+1-w;d=D*Math.log(e/o)+(P-Q+0.5)*Math.log(C/B)+(r-Q)*Math.log(B*M/(o*L))+this.Stirling(e)+this.Stirling(C)-this.Stirling(o)-this.Stirling(B)}if(y<=d){break}}}if(l){return Math.floor(P-r)}else{return Math.floor(r)}}}});a.ui.redlynx.defaults={idPrefix:"ui-redlynx-",initPath:""}})(jQuery);