/* 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},_mkButton:function(b){return a('<a href="#" class="ui-redlynx-'+b.name+' ui-state-default ui-corner-all"><span class="ui-icon ui-icon-refresh"></span>'+b.text+"</a>").hover(function(c,d){a(this).addClass("ui-state-hover")},function(c,d){a(this).removeClass("ui-state-hover")}).mousedown(function(c,d){a(this).addClass("ui-state-active")}).mouseup(function(c,d){a(this).removeClass("ui-state-active")}).click(b.click)},_mkOption:function(d){var b=a('<p class="ui-helper-clearfix"/>');var e=a('<input type="text" value="'+d.value.value+'" size="6"/>');var c=a("<div/>").slider({min:0,max:1024,step:1,range:"min",orientation:"horizontal",value:Math.round(1024*d.funcX(d.value.value)),slide:function(f,g){var h=d.funcY(g.value/1024);d.value.value=parseFloat(h);e.val(h)}});e.change(function(){var f=a(this).val();d.value.value=parseFloat(f);c.slider("value",Math.round(1024*d.funcX(f)))});b.append('<label for="'+this._setID(e)+'" title="'+d.title+'">'+d.label+"</label>").append(e).append(c);return b},_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,e;d=a('<p class="ui-helper-clearfix ui-redlynx-buttons"/>');d.append(this._mkButton({name:"run",text:"Run Simulation",click:function(f,g){f.preventDefault();c.element.redlynx("simulate")}}));d.append(this._mkButton({name:"clear",text:"Clear Graph",click:function(f,g){f.preventDefault();c.element.redlynx("clear_graph")}}));this.$control.append(d);this.$control.size={value:800};this.$control.append(this._mkOption({value:this.$control.size,label:"Population Size:",title:"Number of diploid individuals in the population",funcY:function(f){return Math.round(Math.pow(10,5*f+1))},funcX:function(f){return(Math.log(f)/Math.LN10-1)/5}}));this.$control.start={value:50};this.$control.append(this._mkOption({value:this.$control.start,label:"Initial % of Allele A:",title:"Initial percentage of allele A in the population",funcY:function(f){return Math.round(f*10000)/100},funcX:function(f){return f/100}}));this.$control.sel={value:1};this.$control.append(this._mkOption({value:this.$control.sel,label:"Fitness of AA:",title:"Fitness of genotype AA relative to the fitness of genotype aa",funcY:function(g){var h=Math.pow((g-0.5)*2,3);return Math.round(Math.pow(10,h)*10000)/10000},funcX:function(h){var g=Math.log(h)/Math.LN10;return Math.pow(g,1/3)*0.5+0.5}}));this.$control.dom={value:0.5};this.$control.append(this._mkOption({value:this.$control.dom,label:"Dominance:",title:"Determines how Aa's fitness relates to AA's and aa's",funcY:function(f){return Math.round((3*f-1)*10000)/10000},funcX:function(f){return(f+1)/3}}));this.$control.fmut={value:0};this.$control.append(this._mkOption({value:this.$control.fmut,label:"Forward Mutation:",title:"Probability of a->A mutation",funcY:function(g){if(g==0){return 0}else{if(g>=0.8){var h=10*g-10;return Math.round(Math.pow(10,h)*10000)/10000}else{var h=10*g-10;var i=Math.floor(h);h=Math.round(Math.pow(10,h-i)*100)/100;return(h+"e"+i)}}},funcX:function(f){if(f==0){return 0}return(Math.log(f)/Math.LN10+10)/10}}));this.$control.bmut={value:0};this.$control.append(this._mkOption({value:this.$control.bmut,label:"Backward Mutation:",title:"Probability of A->a mutation",funcY:function(g){if(g==0){return 0}else{if(g>=0.8){var h=10*g-10;return Math.round(Math.pow(10,h)*10000)/10000}else{var h=10*g-10;var i=Math.floor(h);h=Math.round(Math.pow(10,h-i)*100)/100;return(h+"e"+i)}}},funcX:function(f){if(f==0){return 0}return(Math.log(f)/Math.LN10+10)/10}}));this.$control.gens={value:2000};this.$control.append(this._mkOption({value:this.$control.gens,label:"Generations:",title:"Length of a single simulation",funcY:function(f){return Math.round(10000*f)},funcX:function(f){return f/10000}}));this.element.append(this.$control)},simulate:function(){var j=Math.round(this.$control.gens.value);var d=Math.round(this.$control.size.value);var c=this.$control.start.value/100;var x=this.$control.fmut.value;var t=this.$control.bmut.value;var o=this.$control.sel.value;var f=this.$control.dom.value;var s=Math.round(c*2*d);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);