function pp( total, subtotal ) {
    var p = Math.round( subtotal / total * 10000 ) / 100;
    p = Math.abs( p );
    return p + '%';
}

function Question( obj ) {
    
    for ( var key in obj ) {
        var value = obj[key];
        this[key] = value;
    }
    
    return this;    
}

Question.prototype.toHTML = function() {
    var html = '';
    html += '<tr>';
    
    if ( this.type == "input" ) {
        html += '<td><label for="'+this.id+'" class="input-right">' + this.label + '</label></td>';
        html += '<td><input type="text" name="'+this.id+'" id="'+this.id+'" value="" /></td>';
    }
    
    if ( this.type == "yesno" ) {
        html += '<td><span class="input-right">' + this.label + '</span></td>';
        html += '<td><input type="radio" name="'+this.id+'" id="'+this.id+'_yes" value="true" />';
        html += '<label for="'+this.id+'_yes" class="input-left input-right">Yes</label>';
        html += '<input type="radio" name="'+this.id+'" id="'+this.id+'_no" value="false" />';
        html += '<label for="'+this.id+'_no" class="input-left">No</label></td>';
    }
    
    if ( this.type == "list" ) {
        html += '<td><span class="input-right">' + this.label + '</span></td>';
        html += '<td>';
        for ( var i in this.options ) {
            var option = this.options[i];
            html += '<input type="checkbox" id="'+this.id+'_'+i+'" name="'+this.id+'_'+i+'" />';
            html += '<label for="'+this.id+'_'+i+'" class="input-left input-right">' + option.label + '</label>';
        }
        html += '</td>';
        
    }
    html += '</tr>';
    
    return html;
}

Question.prototype.getResults = function( val ) {
    this.result   = '';
    this.value    = 0;
    
    if ( this.customCalc ) {
        this.customCalc( val );
        return;    
    }
    
    if ( this.type == "yesno" ) {
        
        var yes_value = this.yes_value || 0;
        var no_value  = this.no_value || 0;
        
        if ( $('#'+this.id+'_yes').is(":checked") ) {
            this.value = val * yes_value;
        }
        if ( $('#'+this.id+'_no').is(":checked") ) {
            this.value = val * no_value;
        }
        
        if ( this.value != 0) {
            this.result = '<tr class="bbottom"><td>' + this.response + '</td><td>$' + Math.abs(this.value) + '</td><td>'+pp( val, this.value )+'</td></tr>';
        }
        
    }
    
}

function Questionnaire() {
    this.questions = [];
    return this;    
}

Questionnaire.prototype.run = function( obj ) {
    this.qControl     = obj.questions || null;
    this.aControl     = obj.answers || null;
    this.submitButton = obj.button || 'continue';
    
    $( this.aControl ).hide();
       
    if ( this.qControl ) {
        this.showQuestions( this.qControl );
    }
    return this;
}

Questionnaire.prototype.showQuestions = function( control ) {
    var html = '';
    html += '<table>';
    html += '<col style="width: 500px;" />'
    html += '<col />';
    
    html += '<tbody>';
    html += '<tr class="selected">\
                <td><label for="ad-spend" class="input-right">What is your monthly Google AdWords ad spend in US Dollars?</label></td>\
                <td><input type="text" name="ad-spend" id="ad-spend" value="" /></td>\
            </tr>';
    
    for ( var i in this.questions ) {
        var question = this.questions[i];
        html += question.toHTML();
    }
    html += '</tbody>';
    html += '</table>';
    html += '<p class="submit-button mt">\
            <input type="button" name="'+this.submitButton+'" id="'+this.submitButton+'" value="Get Your Results" />\
            </p>';
    
    $( control ).html( html );
    $( control + " input:first" ).focus();
    $( control + ' tr').click( function() {
        $( control + ' tr.selected').removeClass("selected");
        $(this).addClass("selected");
    });
    
    var self = this;
    $( "#" + this.submitButton ).live( "click", function() {
        self.showResults( self.aControl );
    });
    
    return this;
}

Questionnaire.prototype.showResults = function( control ) {
    
    var html = "<h3>Results</h3>";
    $( control ).html( html );
    
    var ad_spend = $("#ad-spend").val();
    
    if ( ad_spend == "" ) {
        $(this.qControl + ' tr.selected').removeClass("selected");
        $(this.qControl + ' tr:first-child').addClass("selected");
        $("#ad-spend").focus();
        return this;    
    }
    
    var total = 0;
    
    var results = "";
    for ( var i in this.questions ) {
        var question = this.questions[i];
        question.getResults( ad_spend );
        results  += question.result;
        total += question.value;
    }
    
    if ( results ) {
        html += '<table><col style="width: 500px;" /><col /><col />' + results + '<tr><td><strong>Total:</td><td><strong>$'+Math.abs(total)+'</strong></td><td><strong>'+pp( ad_spend, total )+'</strong></td></tr></table>';
    }
    
    html += '<div class="summary mt">Of your $'+ad_spend+' ad spend, you are wasting ~ <span style="color: red;">'+pp( ad_spend, total )+'</span> of your ad budget,<br> which costs you ~ <span style="color: red;">$' + Math.abs( total ) + '</span> each month!</div>';
    $( control ).html( html );
    
    $( control ).show('slow');
    var top = $( control ).offset().top;
    $('html,body').animate({scrollTop: top}, 1000);
    
    
    return this;
}

Questionnaire.prototype.addQuestion = function( obj ) {
    this.questions.push( obj );    
    return this;
}

var q = new Questionnaire();

q.addQuestion(
    new Question({
        id: "deep_link",
        label: "Do you deep link to targeted landing pages when possible?",
        type: "yesno",
        no_value: -0.15,
        response: "Not deep linking: "
    })
);

//q.addQuestion(
//    new Question({
//        id: "keywords_per_campaign",
//        label: "How many keywords are in your typical ad campaign?",
//        type: "input"
//    })
//);

q.addQuestion(
    new Question({
        id: "keywords_per_account",
        label: "Roughly how many keywords are in your AdWords account?",
        type: "input"
    })    
);

q.addQuestion(
    new Question({
        id: "groups_per_account",
        label: "Roughly how many ad groups are in your adwords account?",
        type: "input",
        customCalc: function( val ) {
            var groups_per_account   = $("#groups_per_account").val();
            var keywords_per_account = $("#keywords_per_account").val();
            if ( !groups_per_account || !keywords_per_account ) {
                return;
            }
            var recommended_keywords = groups_per_account * 10;
            var excess_keywords = keywords_per_account - recommended_keywords;
            if ( excess_keywords > 9 ) {
                var percentage = Math.round(excess_keywords / 10) * -0.03;
                if ( percentage < -0.15 ) {
                    percentage = -0.15;
                }
                this.value  = val * percentage;
                this.result = '<tr class="bbottom"><td>Having too many keywords per ad group:</td><td>$' + Math.abs(this.value) + '</td><td>'+pp( val, this.value )+'</td></tr>';
            }
        }
    })    
);

q.addQuestion(
    new Question({
        id: "negative_keywords_per_account",
        label: "Roughly how many negative keywords are in your adwords account?",
        type: "input",
        customCalc: function( val ) {
            var negatives = $("#negative_keywords_per_account").val();
            var keywords_per_account = $("#keywords_per_account").val();
            if ( !negatives || !keywords_per_account ) {
                return;
            }
            var recommended_negatives = Math.round(keywords_per_account / 10);
            var missing_negatives = recommended_negatives - negatives;

            if ( missing_negatives > 0 ) {
                var percentage = missing_negatives * -0.03;
                if ( percentage < -0.15 ) {
                    percentage = -0.15;
                }
                this.value  = val * percentage;
                this.result = '<tr class="bbottom"><td>Neglecting negative keywords:</td><td>$' + Math.abs(this.value) + '</td><td>'+pp( val, this.value )+'</td></tr>';                
            }
        }
        
    })
);

q.addQuestion(
    new Question({
        id: "ad_targeting",
        label: "Select the primary keyword match type you currently use:",
        type: "list",
        options: [ { label: "broad match", value: -0.1 }, { label: "phrase match", value: 0 }, { label: "exact match", value: 0 } ],
        customCalc: function ( val ) {
            var broad_match  = $('#' + this.id + '_0').is(":checked");
            var phrase_match = $('#' + this.id + '_1').is(":checked");
            var exact_match  = $('#' + this.id + '_2').is(":checked");
            
            if ( broad_match && !phrase_match && !exact_match ) {
                this.value = val * -0.1;
                this.result = '<tr class="bbottom"><td>Using only broad match:</td><td>$' + this.value* -1 + '</td><td>'+pp( val, this.value )+'</td></tr>';
            }
            
        }
    })
);

q.addQuestion(
    new Question({
        id: "do_you_split_test",
        label: "Do you typically test multiple ads in your adgroups?",
        type: "yesno",
        no_value: -0.1,
        response: "No new ad testing: "
    })  
);

q.addQuestion(
    new Question({
        id: "both_ads_after_split_test",
        label: "If you do test multiple ads, do you delete losing ads once your test is valid?",
        type: "yesno",
        no_value: -0.05,
        response: "Letting losing ads run on 'Rotate' beyond the end of a test: "
    })
);

q.addQuestion(
    new Question({
        id: "search_and_content_ads_together",
        label: "Do you separate your search and content network campaigns?",
        type: "yesno",
        no_value: -0.1,
        response: "Combining search and content targeting in the same campaign: "
    })
);

q.addQuestion(
    new Question({
        id: "exclude_poor_performin_websites",
        label: "If you run content campaigns, do you regularly use the Placement Performance Report to exclude poor-performing websites?",
        type: "yesno",
        no_value: -0.05,
        response: "Not regularly excluding poor-converting content sites from content campaigns: "
    })
);

q.addQuestion(
    new Question({
        id: "ad_geo_targeting",
        label: "Do you target separate campaigns for countries/geographies that have a lower conversion rate?",
        type: "yesno",
        no_value: -0.1,
        response: "Not optimizing campaigns based on geographic conversion rate: "
    })
);

q.addQuestion(
    new Question({
        id: "no_1_bid",
        label: "Do you always bid to position #1 (even during bidding wars)?",
        type: "yesno",
        yes_value: -0.05,
        response: "Always bidding to #1: "
    })  
);

$(document).ready(function() {
    q.run( { questions: '#questions', answers: '#answers' } );
});