var Amplicons = Class.create();

Object.extend(Amplicons,{
    readCookie: function(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }
        return null;
    },

    primerSettings:function() {
        var primer_settings = this.readCookie('primer_settings')
        if(primer_settings) {
            var parts = primer_settings.split('/')
            return {
                'optimal_primer_size': parts[0],
                'minimum_primer_size': parts[1],
                'maximum_primer_size': parts[2],
                'index': parts[3],
                'base_name': parts[4],
                'offset': parts[5],  
                'overlap': parts[6],
                'target_length': parts[7],
                'optTM': parts[8],
                'minTM': parts[9],
                'maxTM': parts[10],
                'maxDiffTM': parts[11]
                
            }
        }
        else
        {
            return null;
        }
    },

    warName: function(){
        var path=location.pathname;
        var a=path.split("/");
        return '/'+a[1];
    },


    set_design_parameters_popup: function() {      
        Amplicon.current = this
        var m = new Control.Modal(false,{
            contents: function(){
                new Ajax.ULRequest(Amplicons.warName()+'/amplicon/parameters?',{
                    onLoading: function() {},
                    onComplete: function(request){
                        m.update(request.responseText);
                    }.bind(this)
                });
            }
        });
        m.open();
    }
})


Amplicons.prototype = {
    initialize: function(options) {
        this.displayGroup = options.displayGroup
        this.features = options.features
        this.options = options
        this.amplicons = new Array();
    },

    build: function() {
        var design_parameters = Amplicons.primerSettings()

        var roiStart = 0;
        var roiEnd = 0;
        var offset = Number(design_parameters.offset)
        var overlap = Number(design_parameters.overlap)
        var idealLength = Number(design_parameters.target_length)
        var index = 0;

        for(var i=0;i<this.features.length;i++){
            roiStart = this.features[i].start_position;

            while(true){
                if((i+1)<this.features.length){
                    if((this.features[i+1].start_position - this.features[i].end_position)<= PADDING){
                        //Then we incorporate the next feature
                        i++;
                    }else{//Then the next feature is beyond the fluff
                        break;
                    }
                }else{//Then we are at the end
                    break;
                }
            }

            roiEnd = this.features[i].end_position;
            roiStart-=100;
            roiEnd+=100;

            //Calculate the number of fragments

            var numOfFragments = Math.ceil((roiEnd-roiStart-overlap)/(idealLength-overlap));

            var fragLength = overlap + Math.round(Math.ceil((roiEnd-roiStart-overlap)/numOfFragments));

            var fragStart = 0;
            var fragEnd = 0;

            for(var k=0;k<numOfFragments;k++){
                fragStart = k*(fragLength-overlap) + roiStart;
                fragEnd = fragStart + fragLength;
                this.amplicons.push(new Amplicon(fragStart,
                fragEnd,
                this.displayGroup.geneSymbol + ':Frag' + index,
                this.options))
                index = index + 1
            }
        }
    },

    draw: function(gene, ratio, begin_index, end_index) {
        var up = true
        for(var i=0;i<this.amplicons.length;i++){
            var amplicon = this.amplicons[i];
            var feature = new Feature(0,
            this.options.flip,
            {feature_type: 'PCR amplicon',
                feature_id: this.displayGroup.geneSymbol + ':Frag' + i,
                object_id: this.displayGroup.geneSymbol + ':Frag' + i,
                validated: 'Pending',
                up: up,
                start_position: amplicon.begin,
                end_position: amplicon.end,
                offset: this.displayGroup.index},
            amplicon.popup.bind(this.amplicons[i]))

            feature.draw(gene, ratio, begin_index, end_index)
            amplicon.indicator('PENDING')
            amplicon.feature = feature
            up = !up
        }
    },

    dump_it: function() {
        var str = this.displayGroup.group
        for(var i=0; i<this.features.length; i++) {
            str += ", [" + this.features[i].start_position + ", " + this.features[i].end_position + "]"
        }

        str += " -- "
        for(var i=0; i<this.amplicons.length; i++) {
            str += ", " + this.amplicons[i].to_s()
        }

        alert(str)
    },

    design_all: function() {
        if(!Amplicons.primerSettings()) {
            alert('There are no primer settings defined.  Please open an amplicon and set them.')
            return
        }
        Element.show('loading')
        this.counter = 0
        for(var i=0;i<this.amplicons.length;i++){
            var amplicon = this.amplicons[i]
            new Ajax.ULRequest(Amplicons.warName()+'/gene/sequence/'+this.options.feature_id+'?&begin=' + (amplicon.begin-200) + "&end=" + (amplicon.end+200), {
                method: 'get',
                onLoading:function(request){},
                onComplete:function(request){},
                onSuccess: this.sequences_generated.bind(this, i)
            });
        }
    },

    sequences_generated: function(index, transport) {
        this.amplicons[index].sequence = eval("(" + transport.responseText + ")");
        this.counter += 1

        if(this.counter == (this.amplicons.length)) {
            this.design()
        }
    },

    design:function() {
        this.counter = 0
        for(var i=0;i<this.amplicons.length;i++){
            var amplicon = this.amplicons[i]
            amplicon.fixup_options()
            new Ajax.ULRequest(this.warName()+'/amplicon/buildAssay/?json=true&' + Hash.toQueryString(amplicon.options)+ '&sequence=' + this.format_sequence(amplicon.sequence) + '&' + Hash.toQueryString($H(Amplicons.primerSettings())) +'&counter='+i, {
                method: 'post',
                onLoading:function(request){},
                onComplete:function(request){},
                onSuccess: this.design_generated.bind(this, i)
            });
        }
    },
  
    warName: function(){
        var path=location.pathname;
        var a=path.split("/");
        return '/'+a[1];
    },

    design_generated: function(index, transport) {
        var amplicon =  this.amplicons[index]
        var response = eval("(" + transport.responseText + ")");
        if(response.error) {
            amplicon.indicator('FAIL')
        } else {
            amplicon.options.set('sequence_1', response.sequence_1)
            amplicon.options.set('sequence_2', response.sequence_2)
            amplicon.options.set('name', response.name)
            amplicon.indicator('SUCCESS')
        }
        this.counter += 1

        if(this.counter == (this.amplicons.length)) {
            Element.hide('loading')
            alert(this.amplicons.select(function(a) {return a.options.get('sequence_1')}).length + " assay(s) were designed.  You may now persist or export the assay(s).")
            var servletType;
            if(this.warName()=='/FeatureBrowser'){
                servletType='Public';
            }else{
                servletType='Private';
            }
            var parameters='http://cgemm-test.louisville.edu/DragDropServlet'+servletType+'/Amplicon?';
            var delimiter="";
            for(var i=0;i<this.amplicons.length;i++){
                parameters+=(delimiter+'pn'+i+"=");
                parameters+=this.amplicons[i].options.get('name');
                parameters+=('&fp'+i+"=");
         
                parameters+=this.amplicons[i].options.get('sequence_1');
                parameters+=('&rp'+i+"=");
                parameters+=this.amplicons[i].options.get('sequence_2');
                delimiter="&";
            }
            
            var element=document.getElementById("drag_all_amplicons");
            var link=document.createElement('a');
            var text = document.createTextNode('Drag all amplicons (Excel)');
            
            link.setAttribute('href',parameters+'&format=excel');
            link.setAttribute('target','_blank');
            
            
            link.appendChild(text);
            
            element.appendChild(link);
        }
    },

    persist:function() {
        Element.show('loading')
        this.counter = 0
        for(var i=0;i<this.amplicons.length;i++){
            var amplicon = this.amplicons[i]
            if(amplicon.options.get('sequence_1')) {
                new Ajax.ULRequest(Amplicons.warName()+'/amplicon/persistAssay/?json=true&' + Hash.toQueryString(amplicon.options)+ '&sequence=' + this.format_sequence(amplicon.sequence), {
                    method: 'post',
                    onLoading:function(request){},
                    onComplete:function(request){},
                    onSuccess: this.persist_generated.bind(this, i)
                });
            }
        }
    },
  
    persist_generated:function(index, transport) {
        this.counter += 1
        var assays_designed = this.amplicons.select(function(a) {return a.options.get('sequence_1')}).length
        if(this.counter == assays_designed) {
            Element.hide('loading')
            alert(assays_designed + ' Assay(s) saved.  The feature will now refresh')
            window.location.reload()
        }
    },

    export_assays: function() {
        var vendor = $('vendors').selectedIndex
        //var product = $('products').selectedIndex
        //NOTE: We are forcing to PCR Primer
        var product = 5

    
        for(var i=0;i<this.amplicons.length;i++){
            var amplicon = this.amplicons[i]
            if(amplicon.options.get('sequence_1')) {
                new Ajax.ULUpdater('feature_cart', Amplicons.warName()+'/gene/addToCart', {
                    onLoading:function(request){Element.show('feature_cart_loading')},
                    onComplete:function(request){window.setTimeout('Element.hide("feature_cart_loading");', 100);},
                    parameters:'id=' + amplicon.options.get('name')+'_F' + "&vendor=" + vendor + "&product=" + product + "&feature_type=" + 'Oligonucleotide' + "&extra=" + amplicon.options.get('sequence_1')
                })
                new Ajax.ULUpdater('feature_cart', Amplicons.warName()+'/gene/addToCart', {
                    onLoading:function(request){Element.show('feature_cart_loading')},
                    onComplete:function(request){window.setTimeout('Element.hide("feature_cart_loading");', 100);},
                    parameters:'id=' + amplicon.options.get('name')+'_R' + "&vendor=" + vendor + "&product=" + product + "&feature_type=" + 'Oligonucleotide' + "&extra="+ amplicon.options.get('sequence_2')
                })


                /*
        new Ajax.ULRequest(this.warName()+'/amplicon/persistAssay/?json=true&' + Hash.toQueryString(amplicon.options)+ '&sequence=' + this.format_sequence(amplicon.sequence), {
          method: 'post',
          onLoading:function(request){},
          onComplete:function(request){},
          onSuccess: this.persist_generated.bind(this, i)
        });
                 */
            }
        }
    },
  
    format_sequence: function(sequence_array) {
        var sequence_string = ''
        for( var i=0; i<sequence_array.length; i++) {
            var sequence = sequence_array[i]
            if(sequence.length == 1) {
                sequence_string += sequence
            }
            else {
                sequence_string += 'N'
            }
        }
    
        return sequence_string
    }
}
