/**
 * Библиотека FLINE (FonBet Line)
 */


/**
 * Объект интерфеса пользователя отвечающий за вывод истории ставок
 */
function FLINE_History(contentBlockId, storage, lang, dwrProxy){
    this.contentBlockId = contentBlockId;
    this.lang = lang;
    this.storage = storage;
    this.dwrProxy = dwrProxy;

    this.couponList = new Array();
    this.couponCounter = 0;
    this.autoClean = getBooleanCookie(this.COOKIE_AUTO_CLEAN_NAME, false);  //автоматически очищать историю ставок
}
//FLINE_History.prototype.CHECK_STATUS_ON_SERVER_TIMEOUT = 6000; //на 1000 больше чем задержка на сервере
FLINE_History.prototype.CHECK_STATUS_ON_SERVER_DELAY = 1000; //доп задержка к задрежке регистрации купона на сервере
FLINE_History.prototype.CHECK_STATUS_ON_SERVER_REPEAT_DELAY = 5000; //задержка перед повторной проверкой
FLINE_History.prototype.CHECK_STATUS_MAX_COUNT = 10; //максимальное количество проверок прежде чем выдать ошибку
FLINE_History.prototype.COOKIE_AUTO_CLEAN_NAME = 'liveBets.couponHistoryAutoClean';
FLINE_History.prototype.COOKIE_AUTO_CLEAN_EXPIRES = new Date(2100,0,1); //1 января 2100-го года
FLINE_History.prototype.AUTO_REJECT_FACTOR_CHANGE = [16090, 16100];  //запрет смены котировки

FLINE_History.prototype.add = function(coupon){
    var cp = new FLINE_HistoryCoupon(this, coupon);
    this.couponList.unshift(cp);
    cp.submit();
    if(this.autoClean) this.clearFinished();
}
FLINE_History.prototype.clear = function(){
    this.couponList = new Array();
    this.paint();
}
FLINE_History.prototype.clearFinished = function(){
    for(var i in this.couponList){
        var cp = this.couponList[i];
        if(cp == null) continue;
        switch(cp.status){
            case 'accepted':
            case 'canceled':
            case 'fatalerr':
            case 'servererr':
                delete this.couponList[i];
        }
    }
}
FLINE_History.prototype.setAutoClean = function(value){
    this.autoClean = value;
    setCookie(this.COOKIE_AUTO_CLEAN_NAME,this.autoClean, this.COOKIE_AUTO_CLEAN_EXPIRES); 
}
FLINE_History.prototype.paint = function(){
    var cb = document.getElementById(this.contentBlockId);
    if(cb == null) return;
    cb.innerHTML = '';
    
    if(this.couponList.length > 0){
        cb.style.display = 'block';
    }else{
        cb.style.display = 'none';
        return;
    }

    var title = document.createElement('div');
    html_set_class(title, 'title');
    title.innerHTML = this.lang.get('history_title');
    cb.appendChild(title);
    
    for(var i in  this.couponList){
        var cp = this.couponList[i];
        cp.paint(cb);
    }
    this.paint_config(cb);
}
FLINE_History.prototype.paint_config = function(container){
    var configDiv = document.createElement("div");
    var autoCleanCBox = document.createElement('input');
    autoCleanCBox.type = "checkbox";
    autoCleanCBox.checked = this.autoClean;
    autoCleanCBox.defaultChecked = this.autoClean; //для IE
    var me = this;
    autoCleanCBox.onclick = function(){
        me.setAutoClean(this.checked);
    }
    configDiv.appendChild(autoCleanCBox);
    var autoCleanText = document.createElement('span');
    autoCleanText.innerHTML += this.lang.get("history_autoClean");
    configDiv.appendChild(autoCleanText);
    container.appendChild(configDiv);
}

function FLINE_HistoryCoupon(history, coupon){
    this.history = history;
    this.lang = history.lang;
    this.storage = history.storage;
    this.lineList = new Array();
    this.cnum = ++history.couponCounter;
    this.id = null;
    this.registrationId = null;
    this.amount = coupon.getAmount();
    this.registeredTime = null;
    this.status = 'sending';
    this.changeMode = coupon.getChangeMode();
    this.statusRequestCount = 0;

    var num = 1;
    for(var i in  coupon.storage.factors){
        var fct = new FLINE_HistoryCouponLine(this, coupon.storage.factors[i], num++);
        this.lineList.push(fct);
    }
}
FLINE_HistoryCoupon.prototype.ID_PREFIX_STATUS  = 'history_coupon_status_';
FLINE_HistoryCoupon.prototype.submit = function(){
    this.history.dwrProxy.placeCoupon(this);
}
FLINE_HistoryCoupon.prototype.checkStatusOnServer = function(){
    this.statusRequestCount++;
    this.history.dwrProxy.checkCouponStatus(this);
}
FLINE_HistoryCoupon.prototype.onCouponServerErrorReceived = function(){
    if( (this.id != null) && (this.statusRequestCount < FLINE_History.prototype.CHECK_STATUS_MAX_COUNT) ){
        this.status = 'servererr';
        this.sheduleStatusUpdateByDelay(FLINE_History.prototype.CHECK_STATUS_ON_SERVER_REPEAT_DELAY);
        return;
    }
    this.status = 'servererr';
    this.history.paint();
    var errTitle = lang.get('history_coupon_title', this.cnum);
    var errDescription = lang.get('coupon_servererr_view_accountHistory');
    var openNow = confirm(errTitle+"\n"+errDescription);
    if(openNow){
        window.open(
            'https://account.fonbet.info/MyAccount/',
            'MyAccount',
            'directories=no,location=no,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no,width=900,height=650'
        );
    }
}
FLINE_HistoryCoupon.prototype.onCouponInfoReceived = function(couponInfo){
    //alert(DWRUtil.toDescriptiveString(couponInfo, 6));
    this.id = couponInfo.id;
    this.loadUpdatedFactorValues(couponInfo);
    this.history.paint(); //для показа номера купона и обновлённых коэф
    switch(couponInfo.status){
        case 'OK':
            this.onCouponInfoReceivedStatusOk(couponInfo)
            break;
        case 'FAIL':
            this.onCouponInfoReceivedStatusFail(couponInfo)
            break;
        default:
            //this should never happen...
            FLINE_Log.error('FLINE_HistoryCoupon.onCouponInfoReceived','Unknown couponInfo status. CouponInfo: '+DWRUtil.toDescriptiveString(couponInfo, 4));
    }
}
FLINE_HistoryCoupon.prototype.onCouponInfoReceivedStatusOk = function(couponInfo){
    //alert('OK: '+DWRUtil.toDescriptiveString(couponInfo, 6));
    switch(couponInfo.state){
        case 'CHECKED':
            this.status = 'wait';
            this.sheduleStatusUpdate(couponInfo);
            break;
        case 'FINISHED':
            this.status = 'accepted';
            this.registrationId = couponInfo.registrationId;
            this.registeredTime = couponInfo.registered;
            break;
        case 'NEW':
        case 'COMPLETE':
        default:
            FLINE_Log.error('FLINE_HistoryCoupon.onCouponInfoReceivedStatusOk', "Coupon #"+couponInfo.id+" state "+couponInfo.state+" is not expected.");
    }
    this.history.paint();
    userAmountRefresh();
}
FLINE_HistoryCoupon.prototype.loadUpdatedFactorValues = function(couponInfo){
    for(var i in couponInfo.lines){
         var lineInfo = couponInfo.lines[i];
         var couponLine = this.findLine(lineInfo.eventId);
        couponLine.updateValue(lineInfo.factorValue);
    }
}
FLINE_HistoryCoupon.prototype.sheduleStatusUpdate = function(couponInfo){
    var delay = FLINE_History.prototype.CHECK_STATUS_ON_SERVER_DELAY + couponInfo.liveDelay;
    //window.setTimeout(function(){me.checkStatusOnServer();}, this.history.CHECK_STATUS_ON_SERVER_TIMEOUT);
    this.sheduleStatusUpdateByDelay(delay);
}
FLINE_HistoryCoupon.prototype.sheduleStatusUpdateByDelay = function(delay){
    var me = this;
    var timer = new FTimer(delay, 1000);
    timer.onTimeout = function(){
        me.checkStatusOnServer();
    }
    timer.onDelta = function(){
        var statusTd = document.getElementById(me.ID_PREFIX_STATUS + me.cnum);
        statusTd.innerHTML = me.lang.get("history_status_wait_timer", Math.floor(this.getTimeToEnd()/1000));
    }
    timer.start();
}
FLINE_HistoryCoupon.prototype.onCouponInfoReceivedStatusFail = function(couponInfo){
    //alert('Error: '+DWRUtil.toDescriptiveString(couponInfo, 6));
    var couponChanges = {
        couponId: this.id,
        lineChangesList: new Array(),
        amountChange: null
    };
    var isRecoverable = false;
    for(var i in couponInfo.errors){
        var errorInfo = couponInfo.errors[i];
        switch(errorInfo.type){
            case 'FACTOR_CHANGED':
                isRecoverable = this.onCouponInfoReceivedStatusFailFactorChanged(couponInfo.id, errorInfo, couponChanges);
                break;
            case 'DEPENDENT_EVENTS':
                isRecoverable = this.onCouponInfoReceivedStatusFailDependentEvents(couponInfo.id, errorInfo, couponChanges);
                break;
            case 'BAD_AMOUNT':
                isRecoverable = this.onCouponInfoReceivedStatusFailBadAmount(couponInfo.id, errorInfo, couponChanges);
                break;
            default:
                isRecoverable = this.onCouponInfoReceivedStatusFailUnknownError(couponInfo.id, errorInfo, couponChanges);
        }
        if(!isRecoverable) break;
    }
    if (isRecoverable) this.history.dwrProxy.changeCoupon(this, couponChanges);
}
FLINE_HistoryCoupon.prototype.onCouponInfoReceivedStatusFailFactorChanged = function(couponId, errorInfo, couponChanges){
    var changedFactorsText = '';
    var errTitle = lang.get('history_coupon_title', this.cnum); 
    var changes = new Array();
    var newFactors = new Array();
    
    for(var i in errorInfo.factorList){
        var changedFactor = errorInfo.factorList[i];
        if(changedFactor == null){
            FLINE_Log.error('FLINE_HistoryCoupon.onCouponInfoReceivedStatusFailFactorChanged', "ChangedFactor not found!");
            return false;
        }
        var couponLine = this.findLine(changedFactor.eventId);
        if(couponLine == null){
            FLINE_Log.error('FLINE_HistoryCoupon.onCouponInfoReceivedStatusFailFactorChanged', "CouponLine for event "+changedFactor.eventId+" not found!");
            return false;
        }
        if(changedFactor.newValue == 0){
            /*
			this.status = 'fatalerr';
			this.history.paint();
			return false;
			*/
            return this.onCouponInfoReceivedStatusFailUnknownError(couponId, errorInfo, couponChanges);
        }
  
        var newFactor = null;
        if(couponLine.factorParam == null){
            newFactor = new FLINE_Factor_OK(couponLine.factorId, couponLine.eventId, couponLine.factorType, couponLine.factorTypeId, couponLine.factorValue);
        }else{
            newFactor = new FLINE_Factor_PARAM(couponLine.factorId, couponLine.eventId, couponLine.factorType, couponLine.factorTypeId, couponLine.factorValue, couponLine.factorParam);
        }
        if(changedFactor.newValue != null) newFactor.value = changedFactor.newValue;
        if(changedFactor.newParam != null) newFactor.param = changedFactor.newParam;

        var scoreChanged = ((changedFactor.newScore != null) && (changedFactor.newScore != couponLine.eventScore)) ;
        newFactor.eventScore = scoreChanged?changedFactor.newScore:couponLine.eventScore;

        var newValueTxt = newFactor.getValue();
        if(newFactor instanceof FLINE_Factor_PARAM){
            newValueTxt += ' ('+newFactor.getParam()+')';
        }
        if(scoreChanged){
            changedFactorsText += lang.get('coupon_bet_scoreOrFactorChanged', couponLine.eventName, newFactor.eventScore, newValueTxt)+"\n";
        }else{
            changedFactorsText += lang.get('coupon_bet_factorChanged', couponLine.eventName, newValueTxt)+"\n";
        }
        changes.push({
            num: couponLine.num,
            newValue: changedFactor.newValue,
            newParam: changedFactor.newParam,
            newScore: changedFactor.newScore
            });
        newFactors.push(newFactor);
    }
    if(changedFactorsText == ''){
        return this.onCouponInfoReceivedStatusFailUnknownError(couponId, errorInfo, couponChanges);
    }
    var errDescription = changedFactorsText+lang.get('coupon_bet_factorChanged_betAnyway')
    //var errDescription = errorInfo.description; 

    if(inArray(FLINE_History.prototype.AUTO_REJECT_FACTOR_CHANGE, changedFactor.factorCode)){ //хак чтобы смена номера Гейма запрещала ставку
        alert(errTitle+"\n"+changedFactorsText);
        accept = false;
    }else{
        var accept = confirm(errTitle+"\n"+errDescription);
    }
    if(accept){
        this.status = 'sending';
        for(var i in changes){
            couponChanges.lineChangesList.push(changes[i]);
        }
        for(var i in newFactors){
            var nf = newFactors[i];
            var cl = this.findLine(nf.eventId);
            cl.updateFromFactor(nf);
        }
    }else{
        this.status = 'canceled';
    }
    this.history.paint();
    return accept;
}
FLINE_HistoryCoupon.prototype.onCouponInfoReceivedStatusFailBadAmount = function(couponId, errorInfo, couponChanges){
    var errTitle = lang.get('history_coupon_title', this.cnum); 
    
    var amountError = errorInfo.amountError;
    
    var currentAmount = amountError.requestedAmount;
    var accept = false;
    var correctInput = false;
    var onlyInteger = false;
    var errDescCode = 'coupon_bet_badAmount';
    if((amountError.minAmount <= currentAmount) && (currentAmount <= amountError.maxAmount)){
        onlyInteger = true;
        errDescCode = 'coupon_bet_badAmount_round';
    }
    do{
        var errDescription = lang.get(errDescCode, currentAmount, amountError.minAmount, amountError.maxAmount);
        var newAmount = currentAmount;
        if(newAmount < amountError.minAmount){
            newAmount = amountError.minAmount;
        }else if(newAmount > amountError.maxAmount){
            newAmount = amountError.maxAmount;
        }
        accept = prompt(errTitle+"\n"+errDescription, newAmount);
        if((accept == null) || (accept == false)){
            accept = false;
            correctInput = true;
        }else{
            if(!accept.match(/^[0-9]*(\.[0-9]*)?$/)) continue;
            currentAmount = parseFloat(accept);
            var intAmount = parseInt(accept);
            if((amountError.minAmount <= currentAmount) && (currentAmount <= amountError.maxAmount)){
                accept = true;
                correctInput = true;
                errDescCode = 'coupon_bet_badAmount';
            }
            if(onlyInteger){
                if(intAmount != currentAmount){
                    correctInput = false;
                    errDescCode = 'coupon_bet_badAmount_round';
                }
            }
        }
    }while(!correctInput);
    
    if(accept){
        this.status = 'sending';
        couponChanges.amountChange = {
            newAmount: currentAmount
        };
        couponChanges.ammountChange = {
            newAmount: currentAmount
        };
        this.amount = currentAmount;
    }else{
        this.status = 'canceled';
    }
    this.history.paint();
    
    return accept;
}
FLINE_HistoryCoupon.prototype.onCouponInfoReceivedStatusFailDependentEvents = function(couponId, errorInfo, couponChanges){
    this.status = 'fatalerr';
    this.history.paint();
    
    
    var errTitle = lang.get('history_coupon_title', this.cnum); 
    var errInfoStr = this.errorInfoFactorListToStrings(errorInfo.factorList);
    //var errDescription = lang.get('coupon_bet_dependentEvents', errInfoStr[0], errInfoStr[1]);
    var errDescription = errorInfo.description; 
    var accept = confirm(errTitle+"\n"+errDescription);
    if(accept){
        this.copyToCurrentCoupon();
    }
    return false;
}
FLINE_HistoryCoupon.prototype.onCouponInfoReceivedStatusFailUnknownError = function(couponId, errorInfo, couponChanges){
    this.status = 'fatalerr';
    this.history.paint();
    
    var errTitle = lang.get('history_coupon_title', this.cnum)+"\n"; 
    //var errDescription = lang.get('history_unknown_error', errorInfo.code);
    var errDescription = lang.get('history_unknown_error', errorInfo.code, errorInfo.description);
    /*
    var errInfoStr = this.errorInfoFactorListToStrings(errorInfo.factorList);
    for(var i in errInfoStr){
	var str = errInfoStr[i];
	errDescription +='\n'+str;
    }
    */
    alert(errTitle+"\n"+errDescription);
    return false;
}
FLINE_HistoryCoupon.prototype.errorInfoFactorListToStrings = function(factorList){
    var strInfo = new Array();
    for(var i in  factorList){
        var f = factorList[i];
        var evtName = '';
        if(f.eventId != null){
            var evt = this.storage.getEvent(f.eventId);
            if(evt != null) evtName = evt.getName();
        }
        var fctName = '';
        if(f.factorCode != null){
            var fct = this.storage.getFactor(f.factorCode);
            if(fct != null) fctName = fct.getTypeInfo()();
        }
        strInfo.push(evtName+' '+fctName);
    }
    return strInfo;
}
FLINE_HistoryCoupon.prototype.findLine = function(eventId){
    for(var i in  this.lineList){
        var ln = this.lineList[i];
        if(ln.eventId == eventId) return ln;
    }
    return null;
}
FLINE_HistoryCoupon.prototype.copyToCurrentCoupon = function(){
    coupon.clear();
    for(var i in  this.lineList){
        var ln = this.lineList[i];
        coupon.addFactor(ln.factorId);
    }
    coupon.setAmount(this.amount);
}
FLINE_HistoryCoupon.prototype.paint = function(block){
    var table = document.createElement('table');
    html_set_class(table, 'coupon');

    this._paint_thead(table);
    this._paint_tbody(table);
   
    block.appendChild(table);
}
FLINE_HistoryCoupon.prototype._paint_thead = function(table){
    var thead = document.createElement('thead');
    
    if(this.id != null){
        var headTitleRow = document.createElement('tr');
        var titleTh = document.createElement('th');
        titleTh.colSpan = 3;
        switch(this.status){
            case 'accepted':
            case 'canceled':
            case 'fatalerr':
                if(userIsCopyCouponAllowed()){
                    var copyBtn = document.createElement('span');
                    html_set_class(copyBtn, 'btn');
                    copyBtn.innerHTML = this.lang.get('history_couponcopyBtn');
                    var me = this;
                    copyBtn.onclick = function(){
                        me.copyToCurrentCoupon()
                        };
                    titleTh.appendChild(copyBtn);
                }
                break;
            default:
        //ничего
        }
        var titleSpan = document.createElement('span');
        titleSpan.innerHTML = lang.get('history_coupon_title', this.cnum);
        titleTh.appendChild(titleSpan);
        headTitleRow.appendChild(titleTh);
        thead.appendChild(headTitleRow);
    }
    
    var headRow = document.createElement('tr');
    var eventTh = document.createElement('th');
    eventTh.innerHTML =  this.lang.get('coupon_fct_event');
    headRow.appendChild(eventTh);
    var typeTh = document.createElement('th');
    typeTh.innerHTML =  this.lang.get('coupon_fct_type');
    headRow.appendChild(typeTh);
    var factValTh = document.createElement('th');
    factValTh.innerHTML =  this.lang.get('coupon_fct_value');
    headRow.appendChild(factValTh);

    thead.appendChild(headRow);
    table.appendChild(thead);
}
FLINE_HistoryCoupon.prototype._paint_tbody = function(table){
    var tbody = document.createElement('tbody');
    
    for(var i in  this.lineList){
        var fct = this.lineList[i];
        var fctRow = document.createElement('tr');
        fct.paint(fctRow);
        tbody.appendChild(fctRow);
    }
    this._paint_tbody_amount(tbody);
    this._paint_tbody_status(tbody);
    
    table.appendChild(tbody);
}
FLINE_HistoryCoupon.prototype._paint_tbody_amount = function(tbody){
    var amountRow = document.createElement('tr');
    var amountNameTd  = document.createElement('td');
    amountNameTd.innerHTML = this.lang.get('coupon_amount_text');
    amountRow.appendChild(amountNameTd);
    
    var amountValueTd  = document.createElement('td');
    html_set_class(amountValueTd, 'amountValue');
    amountValueTd.colSpan = 2;
    amountValueTd.innerHTML = this.amount.toFixed(2);
    amountRow.appendChild(amountValueTd);

    tbody.appendChild(amountRow);
}
FLINE_HistoryCoupon.prototype._paint_tbody_status = function(tbody){
    var statusRow = document.createElement('tr');
    var statusTd  = document.createElement('td');
    statusTd.id = this.ID_PREFIX_STATUS + this.cnum;
    statusTd.colSpan = 3;
    html_set_class(statusRow, 'status');
    html_set_class(statusTd, 'status'+'_'+this.status);
    var statusSpan = document.createElement('span');
    var time = (this.registeredTime == null)?'':formatDate(this.registeredTime,'HH:mm');
    statusSpan.innerHTML = this.lang.get('history_status_'+this.status, time, this.registrationId);
    statusTd.appendChild(statusSpan);
    
    statusRow.appendChild(statusTd);
    tbody.appendChild(statusRow);
}

function FLINE_HistoryCouponLine(coupon, fct, num){
    this.coupon = coupon;
    this.lang = coupon.history.lang;
    this.storage = coupon.history.storage;
    
    var evt = storage.getEvent(fct.eventId);

    this.num = num;
    this.eventNum  = evt.num;
    this.eventName = evt.name;
    this.eventScore = evt.getScoreTextWithoutComment();
    this.factorId = fct.id;
    this.factorType = fct.type;
    this.factorName = fct.getTypeInfo();
    this.factorValueString = fct.getValue();

    this.eventId = fct.eventId;
    this.factorTypeId = fct.typeId;
    this.factorValue = fct.value;
    if(fct.param != null){
        this.factorParam = fct.param;
    }else{
        this.factorParam = null;
    }
}
FLINE_HistoryCouponLine.prototype.updateFromFactor = function(fct){
    this.factorName = fct.getTypeInfo();
    this.factorValueString = fct.getValue();

    this.factorValue = fct.value;
    if(fct instanceof FLINE_Factor_PARAM){
        this.factorParam = fct.param;
    }
}
FLINE_HistoryCouponLine.prototype.updateValue = function(newValue){
    this.factorValue = newValue;
    this.factorValueString = newValue.toFixed(2);
}
FLINE_HistoryCouponLine.prototype.paint = function(row){
    var eventTd = document.createElement('td');
    eventTd.innerHTML = this.lang.get("event_name_with_score", this.eventNum, this.eventName, this.eventScore);
    row.appendChild(eventTd);

    var factorTd = document.createElement('td');
    factorTd.innerHTML = this.factorName;
    row.appendChild(factorTd);
    
    var factorValueTd = document.createElement('td');
    html_set_class(factorValueTd, 'factorValueNormal');
    factorValueTd.innerHTML = this.factorValueString;
    row.appendChild(factorValueTd);
}
loadingJSLoaded++;