var CAPITALBRIDGES = {
    lang : PHP.lang,
    getRevenueLabel : function () { return (this.lang == 'en') ? 'Revenue' : (this.lang == 'es') ? 'Ingreso': 'Lucro'; },
    getCostLabel : function () { return (this.lang == 'en') ? 'Cost' : (this.lang == 'es') ? 'Egreso': 'Custo'; },
    getResultLabel : function () { return (this.lang == 'en') ? 'Free Cash Flow' : (this.lang == 'es') ? 'Flujo de Fondos Libres': 'Lucro Líquido'; },
    getNPVLabel : function () { return (this.lang == 'en') ? 'NPV' : (this.lang == 'es') ? 'VAN' : 'VAL'; },
    getPeriodLabel : function () { return (this.lang == 'en') ? 'Period' : (this.lang == 'es') ? 'Período' : 'Período'; }
}
/*
 *
 */
Array.prototype.toNegative = function() {
    var values = [];

    jQuery.each(this, function(index, item) {
        values.push(-item);
    });

    return values;
}

/*
 * Pair values with two arrays, x axis values with series values
 * @return
 */
Array.prototype.pairWith = function(that) {
    var paired = [];

    if (this.length != that.length)
        return [[0,0]];

    jQuery.each(this,function(index, item) {
        paired.push([item, that[index]]);
    });

    return paired;
}

Array.prototype.range = function (begin, end) {
    for (index = begin; index <= end; index++)
        this.push(index);
}

/*
 *
 */
String.prototype.toInteger = function() {
    //return parseInt(this.replace(/[^-0-9]/g,''));
    return parseInt(this.replace(/[^0-9]/g,''));
}

/*
 *
 */
String.prototype.clean = function() {

    var invalidChar = {
        á : 'a',
        é : 'e',
        í : 'i',
        ó : 'o',
        ú : 'u',
        ñ : 'n'
    };

    // This is the clean method. It calls the string replace method,
    // looking for substrings that
    return function() {
        return this.replace(/á|é|í|ó|ú|ñ/g, function(item, index) {
            r = invalidChar[item];
            return typeof r === 'string' ? r : index;
        });
    }
}();

/*
 *
 *
 */
Number.prototype.toFixedRound = function(n) {
    var N = this;
    N = Math.round(this * Math.pow(10,n));
    N /= Math.pow(10,n);
    return (N.toFixed(n));
}

//Number.prototype.isInteger = function() {
//    return Math.floor(this) == this ? true : false;
//}

/*
 *
 */
jQuery.fn.getValues = function() {
    var values = [];

    this.each(function() {
        value = $(this).html().toInteger();
        values.push(value);
    });
    return values;
}

jQuery.fn.financial = function(options) {
    var opts = jQuery.extend({}, jQuery.fn.financial.defaults, options);

    var updateRate = function () {
        var period = parseInt(opts.period.val());

        switch(period) {
            case 0 : //quarter
                opts.rate = Math.pow(1 + opts.anualRate, 0.25) - 1;
                break;
            case 1 :
                opts.rate = Math.pow(1 + opts.anualRate, 0.5) - 1;
                break;
            default :
                opts.rate = opts.anualRate;
        }
    }

    var updateSeries = function() {
        opts.series.revenues = $('.revenue:visible').fieldValue();
        opts.series.costs    = $('.cost:visible').fieldValue();
        opts.series.results  = [];

        for (index = 0; index < opts.series.revenues.length; index++)
            opts.series.results.push(parseInt(opts.series.revenues[index]) - parseInt(opts.series.costs[index]));
    }

    var updateResults = function() {
        var index = 0;
        $('.result:visible').each(function() {
            $(this).val(opts.series.results[index]); //index + 1 cuando tenga la inversion inicial
            index++;
        });
    }

    var updateCashFlow = function() {
        var investment = $('#investment').val()
        opts.series.cashflow = opts.series.results;
        opts.series.cashflow.unshift(-investment);  // ver
    }

    var updateNPV = function() {
        $('#npv').html('U$S ' + parseInt(opts.getNPV(opts.rate)));
    }

    var updatePBP = function() {
        var pbp = opts.getPBP();
        (pbp != 0) ? $('#pbp').html(pbp + 'º ' + CAPITALBRIDGES.getPeriodLabel()) : $('#pbp').html('-');
    }

    var updateIRR = function() {
        var irr = opts.getAdjustedIRR(opts.getIRR());

        if (isNaN(irr) || irr > 1000 || irr < -1000) opts.index.irr.html('-');
        else opts.index.irr.html((parseInt(irr * 10000 ) /100) + ' %');
    }

    var updateGraph = function() {

        var prepareSeries = function() {
            periods = [];
            periods.range(0, opts.series.cashflow.length - 1);
            opts.series.cashflow = periods.pairWith(opts.series.cashflow);
            periods.shift()
            opts.series.costs = periods.pairWith(opts.series.costs.toNegative());
            opts.series.revenues = periods.pairWith(opts.series.revenues);
        };

        prepareSeries();

        $.plot($("#fcf"), [
            { label: CAPITALBRIDGES.getRevenueLabel(), data: opts.series.revenues, color: "#336699", lines: { show: true }},
            { label: CAPITALBRIDGES.getCostLabel(), data: opts.series.costs, color: "#8a1f11", lines: { show: true }},
            { label: CAPITALBRIDGES.getResultLabel(), data: opts.series.cashflow, color: "#78b96c", lines: { show: true, fill : true }}
        ], {
            yaxis : { tickformatter: function(val, axis) { return (val / 1000) + 'm'; }},
            xaxis : { tickdecimal: 0, tickformatter: function(val, axis) { return val.tofixed(axis.tickdecimal); }},
            grid: { backgroundcolor: "#1c1c1c" },
            legend: { show: true, position: 'se' }
        });
    }

    var update = function() {
        updateSeries();
        updateResults();
        updateCashFlow();
        updateNPV();
        updatePBP();
        updateIRR();
        updateGraph();
    }


    var validateForm = function() {
        var button = $('#submit');
        if (opts.counter.val() > 1 && !opts.hasErrors() && !opts.hasRowFullZeros()) {
            if (button.hasClass('ui-state-disabled')) {
                button.removeClass('ui-state-disabled');
                button.addClass('ui-state-default');
            }
        } else {
            if (button.hasClass('ui-state-default')) {
                button.removeClass('ui-state-default');
                button.addClass('ui-state-disabled');
            }
        }
    }

    /*
     * Is the input value valid.
     */

    return this.each(function() {

        $tabs = $('#project-form-tabs').tabs({
            select : function(evt, ui) {
                if (ui.index == 1) {
                    return opts.isGeneralInformationValid();
                }
                return true;
            },
            show : function(evt, ui) {
                if (ui.index == 1) {
                    updateRate();
                    update();
                    validateForm();
                }
            }
        });

        $('#next-tab').click(function(evt) {
            evt.preventDefault();
            $tabs.tabs('select', 1);
        });

        $('#previous-tab').click(function(evt) {
            evt.preventDefault();
            $tabs.tabs('select', 0);
        });

        // change events //
        $('#country').change(function() {
            $('#state').load('/' + CAPITALBRIDGES.lang +'/async/get-states/format/html', { country : $(this).val() });
        });

        $('#industry').change(function() {
            $('#sector').load('/' + CAPITALBRIDGES.lang + '/async/get-sectors/format/html', { industry : $(this).val() });
        });

        $('#period').change(function() {
            updateRate();
            update();
        });

        $(this).find('.value').change(function() {
            if (opts.isElementValid(this) && !opts.hasErrors())
                update();
            validateForm();
        });

        $('#investment').change(function() {
            if (opts.isElementValid(this) && !opts.hasErrors())
                update();
            validateForm();
        });

        // attach al puto formulario counter bigger that 3
        opts.counter = $('#counter');

        $('#cash-flow-table tbody tr:gt(' + opts.counter.val() + ')').hide();

        $("#remove-row").click(function(evt) {
            evt.preventDefault();
            if (opts.counter.val() == 0 || opts.hasErrors()) return;

            $('#cash-flow-table tbody tr').filter('tr:eq(' + opts.counter.val() + ')').hide();

            opts.counter.val(parseInt(opts.counter.val()) - 1);
            update();
            validateForm();
        });

        $("#add-row").click(function(evt) {
            evt.preventDefault();
            if (opts.counter.val() == 9 || opts.hasErrors()) return;

            $('#cash-flow-table tbody tr:hidden:first').show();
            opts.counter.val(parseInt(opts.counter.val()) + 1);
            update();
            validateForm();
        });
    });

}

jQuery.fn.financial.defaults = {
    series : {},
    cashFlowErrors : 0,
    period : $('#period'),
    index :
        {
            rate    : $('#rate'),
            beta    : $('#beta'),
            vpn     : $('#vpn'),
            irr     : $('#irr'),
            pbp     : $('#pbp')
        },
    setRates : function() {
        var country = $('#country').val();
        var industry = $('#industry').val();

        that = this;

        var options = {
            async : false,
            url : '/es/async/get-rates/format/json',
            data : { country: country, industry : industry },
            success : function (data) {
                that.anualRate = (parseInt(data.rates.rate) * 100) / 10000;

                that.index.rate.html(data.rates.rate + ' %');
                that.index.beta.html(data.rates.beta);
            },
            dataType : 'json'
        };

        $.ajax(options);
    },
    getNPV : function(rate) {
        rate = (rate === null) ? this.rate : rate;
        var result = 0;

        for (var index = 0; index < this.series.cashflow.length; index++)
            result += this.series.cashflow[index] / Math.pow((1 + rate), index);

        return result;
    },
    getPBP : function() {
        var result = 0;

        for (var index = 0; index < this.series.cashflow.length; index++) {
            result += this.series.cashflow[index] / Math.pow((1 + this.rate), index);
            if (result > 0) return index;
        }

        return 0;
    },
    getIRR : function() {
        var MAX_ITERATIONS = 50;
        var ACCURANCY = 0.001;
        var x1 = 0.0;
        var x2 = 0.2;

        abs = Math.abs;

        var bottom = this.getNPV(x1);
        var top = this.getNPV(x2);

        for (index = 0; index < MAX_ITERATIONS; index++) {
            if ((bottom * top) < 0.0) { break; }

            if (abs(bottom) < abs(top)) {
                bottom = this.getNPV(x1 += 1.6 * (x1 - x2));
            } else {
                top = this.getNPV(x2 += 1.6 * (x2 - x1));
            }
        }

        if (top * bottom > 0.0) { return NaN; }

        var f = this.getNPV(x1);
        var rtb;
        var dx = 0;

        if ( f < 0.0) {
            rtb = x1;
            dx  = x2 - x1;
        } else {
            rtb = x2;
            dx  = x1 - x2;
        }

        for (index = 0; index < MAX_ITERATIONS; index++) {
            dx *= 0.5;
            xmid = rtb + dx;
            fmid = this.getNPV(xmid);

            if (fmid <= 0.0) { rtb = xmid; }
            if ((abs(fmid) < ACCURANCY) || (abs(dx) < ACCURANCY)) { return xmid; }
        }

        return NaN;
    },

    getAdjustedIRR : function(irr) {
        var period = parseInt(this.period.val());
        switch (period) {
            case 0:
                return Math.pow(1 + irr, 4) - 1;
                break;
            case 1:
                return Math.pow(1 + irr, 2) - 1;
                break;
            default:
                return irr;
        }
    },

    isElementValid : function(elt) {

        var isInteger = function(value) { return /^(0|[1-9]\d*)$/.test(value); } //FIXME

        elt = $(elt);
        trimmed = $.trim(elt.val());

        if (trimmed == null || trimmed == '')
            trimmed = 0;

        if (isInteger(trimmed)) {
            elt.val(trimmed);
            if (elt.hasClass('notValid')) { elt.removeClass('notValid'); this.cashFlowErrors -= 1; }
            return true
        }  else {
            if (!elt.hasClass('notValid')) { elt.addClass('notValid'); this.cashFlowErrors += 1; }
            return false
        }
    },

    hasErrors:function() {
        return (this.cashFlowErrors != 0) ? true : false;
    },

    hasRowFullZeros : function() {
        has = false;
        $('#cash-flow-table tbody tr:not(:hidden)').each(function () {
            values = $(this).find('.value').fieldValue();
            var cuenta = 0;
            for (var i = 0; i < values.length; i++) {
                if (parseInt(values[i]) == 0)
                    cuenta++;
            }

            if (cuenta == 3)
                has = true;
        });
        return has;
    },

    isGeneralInformationValid : function() {
        var isValid = false;

        var processJSON = function (data, statusText, jqForm) {
            removeExistingErrorMessages();

            if (!data.messages) { //FIXME
                isValid = true;
                return;
            }

            var form = jqForm[0];
            var errorMessages = data.messages.generalInfo

            $.each(form, function(key, elt) {
                if (errorMessages[elt.name]) {
                    addErrorMessagesTo(form[key], errorMessages[elt.name]);
                }
            });
        };

        var addErrorMessagesTo = function (elt, errorMessages) {
            var errorsHtml = '';
            var width = (elt.id == 'project') ? '21': '10-5';
            errorsHtml += '<div class="span-' + width + ' last error">';

            $.each(errorMessages, function(errorCode, message) {
                errorsHtml += message + '<br/>';
            });

            errorsHtml += '</div>';
            $(elt).after(errorsHtml);
        };

        var removeExistingErrorMessages = function() {
            $('div#tab-1 div.error').remove();
        };

        var options = {
            async :         false,
            url :           '/' + CAPITALBRIDGES.lang + '/async/validate-general-info/format/json',
            success :       processJSON,
            dataType :      'json'
        };

        $('#project-form').ajaxSubmit(options);

        this.setRates();

        return isValid;
    }
}

var addFormHandlers = function() {
    // refactor
    var options = {
        target: '#login-container',
        success : function() {
            addFormHandlers.apply(this);
            addClickHandlers.apply(this);
            addButtonsEffects.apply(this);
            addInlineLabels.apply(this);
        }
    };

    // refactor make it an ID
    $(".remote", this).ajaxForm(options);

    options = {
        target: '#ajax-container',
        success : function() {
            addFormHandlers.apply(this);
            addClickHandlers.apply(this);
            addButtonsEffects.apply(this);
        }
    };

    $("#ilikeitForm", this).ajaxForm(options);
    $("#changeForm", this).ajaxForm(options);

    $('#project-form').financial();
}

var addClickHandlers = function() {

    $('a.submit-button').click(function(evt) {
        evt.preventDefault();
        target = $(evt.target);
        if (!target.hasClass('ui-state-disabled'))
            target.closest("form").submit();
    });

    // fix ain't the best way to handle

    $('#open-inline-help').click(function(evt) {
        evt.preventDefault();
        $('#inline-help').fadeIn();
    });

    $('#close-inline-help').click(function(evt) {
        evt.preventDefault();
        $(this).closest('div').fadeOut();
    });

    $('.close').click(function(evt) {
        evt.preventDefault();
        that = $(this).closest('span').hide();
        $(that).prev('a.open').fadeIn();

    })
    $('.open').click(function(evt) {
        $(this).next('span.delete').fadeIn();
        $(this).hide();
    })
};

var addTableHandlers = function() {
    var $table = $('#projects-grid');

    // if table not exists E
    if (!$table.length) { return; }

    $table.tablesorter(
        {
            debug:                  false,
            sortList:               [[0,0]],
            widgets:                ['zebra']
        }
    ).bind("sortEnd", function(evt) {

        $table.find('thead a').each(function() {
            $th = $(this).closest('th');
            if ( $th.hasClass('headerSortDown') ) {
                $(this).addClass('ui-state-active');
                $(this).children('span').addClass('ui-icon-carat-1-s').removeClass('ui-icon-carat-2-n-s').removeClass('ui-icon-carat-1-n');
            }
            if ( $th.hasClass('headerSortUp') ) {
                $(this).addClass('ui-state-active');
                $(this).children('span').addClass('ui-icon-carat-1-n').removeClass('ui-icon-carat-2-n-s').removeClass('ui-icon-carat-1-s');
            }
            if ( !$th.hasClass('headerSortDown') && !$th.hasClass('headerSortUp') ) {
                $(this).removeClass('ui-state-active');
                $(this).children('span').addClass('ui-icon-carat-2-n-s').removeClass('ui-icon-carat-1-s').removeClass('ui-icon-carat-1-n');
            }
        });
    });


    if (!$table.hasClass('pagerable')) { return; }

    $table.tablesorterPager({
        container:              $("#pager"),
        positionFixed:          false
    });

    $table.tablesorterFilter({
        filterContainer:        $("#filter-by-keyword"),
        filterClearContainer:   $("#filter-by-keyword-clear"),
        filterColumns:          [0, 2, 3, 4, 5],
        filterCaseSensitive:    false,
        filterWaitTime:         1000
    },{
        filterContainer:        $('#filter-hidden'),
        filterClearContainer:   null,
        filterColumns:           [1],
        filterCaseSensitive:    false
    }).bind('filterEnd', function(evt) {
        if ($(this).find('tbody').children().length == 0 ) {
            $('#ui-wrapper').hide();
            $('#no-results').show();
        } else {
            $('#ui-wrapper').show();
            $('#no-results').hide();
        }
    });

    $('#filter-select-proxy').change(function() {
        $('#filter-hidden').val($(this).val()).trigger('keyup');
    });

    if ($('#filter-hidden').val() == 2)
        $('#filter-hidden').trigger('keyup');
}

var addButtonsEffects = function() {
    $(".fg-button:not(.ui-state-disabled)")
        .hover(function() { $(this).addClass('ui-state-hover'); }, function() { $(this).removeClass('ui-state-hover'); })
        .mousedown(function () { $(this).addClass('ui-state-active'); })
        .mouseup(function() { $(this).removeClass('ui-state-active'); });
}

/**
 * Adds inline labels to login form if present
 *
 * @return  void
 */
var addInlineLabels = function() {

    $('#login_email').focus(function(evt) {
        this.value = '';
    }).blur(function(evt) {
        if (this.value == '') { this.value = this.defaultValue; }
    });

    $('#login_password').focus(function(evt) {
        if (isIE()) {
            replaceInputElement(this);
        } else {
            this.value = '';
            this.type = 'password'; //not working with IE
        }
    }).blur(function(evt) {
        if (this.value == '') {
            this.type = 'text';
            this.value = this.defaultValue;
        }
    });

    /**
     * Return true if user browser is IE
     * @return  boolean
     */
    var isIE = function() {
        return !$.support.leadingWhitespace;
    }

    /**
     * Replace input element with an inline label with a password element
     * @param   element
     * @return  void
     */
    var replaceInputElement = function (elt) {
        var input = '<input id="login_password" type="password" name="login_password" class="normal" value="" />';
        $(elt).replaceWith(input);
    }
}

var addTabs = function() {

    $tabs = $('#project-details-tabs').tabs({
        wasShown : false,
        show : function(evt, ui) {
            if (ui.index == 1 && !this.wasShown) {
                addGraphs();
                this.wasShown = true;
            }
        }
    });

    $('.next-tab').click(function(evt) {
        evt.preventDefault();
        var selected = $tabs.tabs('option', 'selected');
        if (selected < 2) {
            $tabs.tabs('select', selected + 1);
        }
    });

    $('.previous-tab').click(function(evt) {
        evt.preventDefault();
        var selected = $tabs.tabs('option', 'selected');
        if (selected > 0) {
            $tabs.tabs('select', selected - 1);
        }
    });

    $('#profile-tabs').tabs();
}


var addGraphs = function() {

        var investment = $('#cash-flow-investment').getValues().toNegative();
        var revenues = $('#project-cash-flow .revenue').getValues();
        var costs = $('#project-cash-flow .cost').getValues().toNegative();
        var results = $('#project-cash-flow .result').getValues();
        results.unshift(investment[0]);

        var periods = [];
        periods.range(0, results.length - 1)

        var resultSerie = periods.pairWith(results);

        periods.shift();

        var revenueSerie = periods.pairWith(revenues);
        var costSerie = periods.pairWith(costs);

        var percent = $('#project-npv-profile .period').getValues();
        var vpn = $('#project-npv-profile .result').getValues();

        var d4 = percent.pairWith(vpn);
        var max = $('#irr').getValues() / 100;

    $.plot($("#fcf"), [
        { label: CAPITALBRIDGES.getRevenueLabel(), data: revenueSerie, color: "#336699", lines: { show: true }},
        { label: CAPITALBRIDGES.getCostLabel(), data: costSerie, color: "#8a1f11", lines: { show: true }},
        { label: CAPITALBRIDGES.getResultLabel(), data: resultSerie, color: "#78b96c", lines: { show: true, fill : true }}
    ], {
        yaxis : { tickFormatter: function(val, axis) { if (val > 1000000) { return (val / 1000000) + 'm' } else { return (val/1000); } }},
        xaxis : { tickdecimal: 0, tickformatter: function(val, axis) { return val.tofixed(axis.tickdecimal); }},
        grid: { backgroundcolor: "#1c1c1c" },
        legend: { show: true, position: 'se' }
    });

    $.plot($("#pvan"), [
        { label: CAPITALBRIDGES.getNPVLabel(), data: d4, lines: { show: true }, points: { show: true }}
    ], {
        yaxis : { tickFormatter: function(val, axis) { if (val > 1000000) { return (val / 1000000) + 'm' } else { return (val/1000); } }},
        xaxis : { min: 0, max: max , tickFormatter: function(val, axis) { return val + '%'; }},
        grid: { backgroundColor: "#1c1c1c" }
    });
}

var addSlideshow = function () {

    var bannerContainer = $('#photo');
    var nextImg = 1;

    start = function() {
        bannerContainer.fadeOut(2000, function() {
            prevImg = (nextImg == 1) ? 4 : nextImg - 1 ;
            $(this).removeClass('img-' + prevImg);
            $(this).addClass('img-' + nextImg);
        }).fadeIn(500);

        nextImg < 4 ? nextImg++ : nextImg = 1;
    }
  //  start = function() {
  //      bannerContainer.fadeOut(2000, function() {
  //          $(this).('src', imgs[nextImg].src);
  //      }).fadeIn(500);

  //      nextImg != 3 ? nextImg++ : nextImg = 0;
  //  }
    setInterval("start()", 10000);
}


init = function() {
    addTableHandlers.apply(this);
    addClickHandlers.apply(this);
    addButtonsEffects.apply(this);
    addInlineLabels.apply(this);
    addTabs.apply(this);
    addFormHandlers.apply(this);
    addSlideshow.apply(this);
}

$(document).ready(init);

