var lastRandomSeed = 0;
function SetParams(allParams) {
    var app = App();
    if (app == null) return;
    app.setPackInBunker(document.FmMain.CPackInBunker.checked); // should be before SetNeedObjCount
    if (allParams) {
        app.setNeedObjCount(0);
        app.setMaxObjCount(parseInt(document.FmMain.TMaxObjCount.value));
        app.setMaxAverageGeneratrixSegmentsCount(parseFloat(document.FmMain.TMaxAverageGeneratrixSegmentsCount.value));
        SetNeedObjCount(false);
        app.setGridXDim(parseInt(document.FmMain.TGridDim.value));
        app.setGridYDim(parseInt(document.FmMain.TGridDim.value));
        app.setGridZDim(parseInt(document.FmMain.TGridDim.value));
        document.FmMain.TGridDim.value=app.getGridXDim();
    }
    app.setPackingKind(document.FmMain.DPackingKind.options.selectedIndex);
    if (document.FmMain.DPackingKind.options.selectedIndex==2)
        if (document.FmMain.DSameColorNeighboursCount.selectedIndex>1)
            document.FmMain.DSameColorNeighboursCount.selectedIndex=1;

    var bunX = parseFloat(document.FmMain.TBunX.value);
    var bunY = parseFloat(document.FmMain.TBunY.value);
    var bunZ = parseFloat(document.FmMain.TBunZ.value);
    if (!isNaN(bunX)) app.setBunX(bunX);
    if (!isNaN(bunY)) app.setBunY(bunY);
    if (!isNaN(bunZ)) app.setBunZ(bunZ);
    app.setBunColors(document.FmMain.TBunColors.value);
    app.setNearestFrom(parseInt(document.FmMain.TNearestFrom.value));
    app.setRandomRotating(document.FmMain.CRandomRotating.checked);
    app.setCompactnessFactor(parseInt(document.FmMain.TCompactnessFactor.value));
    app.setRandomRadiusModel(document.FmMain.DRandomRadiusModel.selectedIndex);
    app.setRandomRadiusModel2(document.FmMain.DRandomRadiusModel2.selectedIndex);
    app.setRandomRadiusIncrementModel(document.FmMain.DRandomRadiusIncrementModel.selectedIndex);
    var MeanR = document.FmMain.TMeanR.value + "";   // a string, not a number!
    var meanr = document.FmMain.TMeanR2.value + "";  // a string, not a number!
    var MeanRI = document.FmMain.TMeanRI.value + ""; // a string, not a number!
    var DR = document.FmMain.TDR.value + "";         // a string, not a number!
    var DR2 = document.FmMain.TDR2.value + "";       // a string, not a number!
    var DRI = document.FmMain.TDRI.value + "";       // a string, not a number!
    if (DR.indexOf(",") == -1) DR = app.sDouble(parseFloat(eval(DR)),-1);    // "3.14" format, not "3,14"!
    if (DR2.indexOf(",") == -1) DR2 = app.sDouble(parseFloat(eval(DR2)),-1); // "3.14" format, not "3,14"!
    if (DRI.indexOf(",") == -1) DRI = app.sDouble(parseFloat(eval(DRI)),-1); // "3.14" format, not "3,14"!
    app.setMeanR(MeanR);
    app.setDR(DR);
    app.setMeanR2(meanr);
    app.setDR2(DR2);
    app.setMeanRI(MeanRI);
    app.setDRI(DRI);

    var x,y,z,v;
    app.setSpherePolyhedraKinds(document.FmMain.TSpherePolyhedraKinds.value);
    app.setFractionsOfKinds(document.FmMain.TFractionsOfKinds.value);
    app.setVolumeFractionsMode(document.FmMain.CVolumeFractionsMode.checked);
    app.setPreferredDirections(document.FmMain.TPreferredDirections.value);
    app.setPreferredDirectionsDFi(document.FmMain.TPreferredDirectionsDFi.value);
    app.setPreferredDirectionsCount(parseInt(document.FmMain.TPreferredDirectionsCount.value));
    app.setPreferredStartX(isNaN(x=parseFloat(document.FmMain.TPreferredStartX.value))?0:x);
    app.setPreferredStartY(isNaN(y=parseFloat(document.FmMain.TPreferredStartY.value))?0:y);
//	app.setPreferredStartZ(isNaN(z=parseFloat(document.FmMain.TPreferredStartZ.value))?0:z); // not suppotted yet
    app.setPreferredStartDX(isNaN(x) || isNaN(v=parseFloat(document.FmMain.TPreferredStartDX.value))?-1:v);
    app.setPreferredStartDY(isNaN(y) || isNaN(v=parseFloat(document.FmMain.TPreferredStartDY.value))?-1:v);
//	app.setPreferredStartDZ(isNaN(z) || isNaN(v=parseFloat(document.FmMain.TPreferredStartDZ.value))?-1:v);
    app.setUsedColors(document.FmMain.TUsedColors.value);
    app.setGridStep(parseFloat(document.FmMain.TGridStep.value));
    var rni= parseInt(document.FmMain.TRequiredNeighbourIndex.value);
    app.setRequiredNeighbourIndex(isNaN(rni)? -1: rni-1);
    app.setSameColorNeighboursCount(document.FmMain.DSameColorNeighboursCount.selectedIndex);
    app.setMaxInvisibleNeighboursCount(3-document.FmMain.DMaxInvisibleNeighboursCount.selectedIndex);
    app.setNonRestrictedObjCount(parseInt(document.FmMain.TNonRestrictedObjCount.value));
    app.setRestrictedMaxD(isNaN(v=parseFloat(eval(document.FmMain.TRestrictedMaxD.value)))?-1.0:v);
    app.setWarningWhenCannotPack(document.FmMain.CWarningWhenCannotPack.checked);
    app.setCheckAllPositions(document.FmMain.CCheckAllPositions.checked);
    app.setPackTimeOut(parseFloat(document.FmMain.TPackTimeOut.value));
    app.setSleepDelay(parseInt(document.FmMain.TSleepDelay.value));
}

function SetNeedObjCount(buttonApply,wnd) {
    var app = App();
    if (app == null) return;
    if (buttonApply) {
        if (app.getObjCount()<=app.getSpecialObjCount()) {
            PageExecute();
            return;
        }
        if (app.getObjCount() <= 100) {
            app.setAuthorized(false);
            if (!AskAuthorizationOrConfirmationForLargePack("SetNeedObjCount(true)",wnd))
                return;
        }
    }
    var needcount = parseInt(document.FmMain.TNeedObjCount.value);
    app.setNeedObjCount(needcount);
    document.FmMain.TNeedObjCount.value=app.getNeedObjCount();
    if (buttonApply) {if (!onTimerActive) {onTimerActive=true; onTimer();}}
}

function CalculateRequiredMemory() {
    var app = App();
    if (app == null) return;
    document.FmMain.TMemoryInfoObjects.value=
        app.sDouble(document.FmMain.TMaxObjCount.value
            *51.0/1024.0/1024.0,3);
        /* 51:
            AlgorithmPackingMink:
                objX/Y/Z, sphR, objV:   5*4
                genR:                   2
                genOfs, objNext:        2*4
                objD:                   4
                objC:                   1
                indices:                4
                                        =39
            SpImageBuilder:
                zGrid:                  4
                objNext:                4
                                        =8
            StatisticsQuick:
                neighbours:             4
        */

    document.FmMain.TMemoryInfoGeneratrixSegments.value=
        app.sDouble(
            document.FmMain.TMaxObjCount.value*
            document.FmMain.TMaxAverageGeneratrixSegmentsCount.value*
            6.0/1024.0/1024.0,3);
        /* 6:
            AlgorithmPackingMink:
                genSegmentsXYZ:         3*2
        */
    document.FmMain.TMemoryInfoGrid.value=
        app.sDouble(Math.pow(document.FmMain.TGridDim.value,3)*4.0/1024.0/1024.0,3);
}

var ExecuteDisabled = false;
function PageApply() {
    SetNeedObjCount(true);
}

function PageExecute(noconfirm,wnd) {
    var app = App();
    if (app == null) return;
    if (ExecuteDisabled) return;
    if (!checkVersion(app)) return;
    app.setAuthorized(false);
    if (!AskAuthorizationOrConfirmationForLargePack("PageExecute(true)",wnd)) return;

    if ((noconfirm==null || !noconfirm) && app.getObjCount()>app.getSpecialObjCount()) {
        if (!confirm('The "Execute" button fully rebuilds the pack. '
            +'So, the current pack ('+app.getObjCount()+' objects) '
            +'will be permanently lost.\n'
            +'To save it before building a new pack, you may use '
            +'the "Build detailed report" button in the "Report" section.\n\n'
            +'Do you really want to build a new pack?')) return;
    }

    ExecuteDisabled=true;
    StopDemoRotate();
    app.stopRunning();
    app.clearPack();    // allows to add bunker
    SetParams(true);
    app.clearPack();    // adds bunker
    SetPaintParams();
    if (document.FmMain.CReproducibleResults.checked)
        app.resetRandomSequence(lastRandomSeed=0);
    else
        lastRandomSeed = app.newRandomSequence();
    app.startRunning();
    if (!onTimerActive) {onTimerActive=true; onTimer();}
    if (!onTimerPaintActive) {onTimerPaintActive=true; onTimerPaint();}
    ExecuteDisabled=false;
}

function Stop() {
    var app = App();
    if (app == null) return;
    if (app.getNeedObjCount()<=app.getSpecialObjCount()) return;
    var count = app.getObjCount();
    app.setNeedObjCount(count);
    document.FmMain.TNeedObjCount.value=app.getNeedObjCount();
    top.scenario = null;
}

function Repaint() {
    var app = App();
    if (app == null) return;
    app.requestRedraw();
    app.calculateStatistics();
    onTimer();
}

function StartWithCurrentObjCount() {
    var app = App();
    if (app == null) return;
    StopDemoRotate();
    app.stopRunning();
    app.setNeedObjCount(app.getObjCount());
    app.startRunning();
}

function Dilation() {
    var app = App();
    if (app == null) return;
    var s = document.FmMain.TDilatedObjects.value;
    var n = parseInt(s);
    var MeanR = parseFloat(document.FmMain.TMeanR.value);
    var meanr = parseFloat(document.FmMain.TMeanR2.value);
    var MeanRI = parseFloat(document.FmMain.TMeanRI.value);
    var r = eval(document.FmMain.TAddedR.value);
    if (!isNaN(n))
        app.dilation(n,r);
    else
        app.dilationGivenColors(s,r);
}

function BlinkProgress(enabled,packingProblem) {
    var s = ' ';
    if (enabled)
        s = packingProblem? 'Packing problem! ':
            enabled==2? 'Finished': 'R u n n i n g ...';

    var onerrorSaveLocal = window.onerror;
    window.onerror = null;  // - avoiding an incorrect exception in Netscape Navigator 3
                            // ("Can't reflect applet "(null)": not loaded yet")
                            // sometimes appeared while accessing non-existing document fields
    var hasGetElementById = document.getElementById != null;
    window.onerror = onerrorSaveLocal;

    if (window.SpanProgress != null && SpanProgress.innerHTML != null) {
        if (packingProblem)
            s+= '<a href="help/packingproblem.html" target="PackingMinkHelp" '
                +'language="JavaScript" onclick="return ShowHelp(href)">Help</a>';
        SpanProgress.innerHTML = s;
    } else if (hasGetElementById) {
        var e = document.getElementById("SpanProgress");
        while (e.lastChild != null) e.removeChild(e.lastChild);
        var es = document.createTextNode(s);
        e.appendChild(es);
        if (packingProblem) {
            var ea = document.createElement("a");
            ea.setAttribute("href","help/packingproblem.html");
            ea.setAttribute("target","PackingMinkHelp");
            ea.setAttribute("language","JavaScript");
            ea.setAttribute("onclick","return ShowHelp(href)");
            ea.appendChild(document.createTextNode("Help"));
            e.appendChild(ea);
        }
    }
}

var onTimerActive = false;
function onTimer() {
    var app = App();
    if (app == null) return;
    ExecuteDisabled=true;
    var Ok = app.isRunningOk();
    if (!Ok) StopDemoRotate();
    if (document.FmMain.CRepaintWhilePacking.checked)
        app.requestRedraw();
    if (document.FmMain.CCalcParametersWhileRunning.checked)
        app.requestStatistics();
    document.FmPaint.TObjCount.value = app.getObjCount();
    var D = app.getPackInBunker()? app.getMaxZ()-app.getMinZ(): app.getMaxD(); // for evals
    var V = app.getSumV(), sx, sy, sz;
    document.FmResults.TMaxD.value = app.sDouble(app.getMaxD()*1.0,5);
    document.FmResults.TMinX.value = app.sDouble(app.getMinX()*1.0,3);
    document.FmResults.TMaxX.value = app.sDouble(app.getMaxX()*1.0,3);
    document.FmResults.TMinY.value = app.sDouble(app.getMinY()*1.0,3);
    document.FmResults.TMaxY.value = app.sDouble(app.getMaxY()*1.0,3);
    document.FmResults.TMinZ.value = app.sDouble(app.getMinZ()*1.0,3);
    document.FmResults.TMaxZ.value = app.sDouble(app.getMaxZ()*1.0,3);
    document.FmResults.TSX.value = app.sDouble(sx=(app.getMaxX()-app.getMinX())*1.0,5);
    document.FmResults.TSY.value = app.sDouble(sy=(app.getMaxY()-app.getMinY())*1.0,5);
    document.FmResults.TSZ.value = app.sDouble(sz=(app.getMaxZ()-app.getMinZ())*1.0,5);
    document.FmResults.TXYZ.value = app.sDouble(sx*sy*sz,5);
    document.FmResults.TSumV.value = app.sDouble(V,5);
    var s = "", cc = app.getColorCharacters()+""; // +"" is necessary in Mozilla, where this method returns JAVA String object
    var N = app.getObjCount();
    for (var k = 0; k < cc.length; k++) {
        var n = app.getObjCountPerColor(k);
        if (n <= 0) continue;
        var v = app.getObjVolumePerColor(k);
        s += cc.charAt(k) + ": "
            + pad(n,5) + " "
            + pad(app.sDouble(100.0*n/N,1)+"%;",6) + " "
            + pad(app.sDouble(v/n,5),10) + "; "
            + pad(app.sDouble(v,2),10) + " "
            + pad(app.sDouble(100.0*v/V,1)+"%",5) + "\n";
    }
    document.FmResults.TStatisticsBasic.value = s;
    if (document.FmMain.CCalcParametersWhileRunning.checked || Ok) {
        document.FmResults.TDensity1.value = density(eval(document.FmResults.TDensityEval1.value),"\261");
        document.FmResults.TDensity2.value = density(eval(document.FmResults.TDensityEval2.value),"\261");
        document.FmResults.TDensity3.value = density(eval(document.FmResults.TDensityEval3.value),"\261");
        document.FmResults.TDensity4.value = density(eval(document.FmResults.TDensityEval4.value),"\261");
        document.FmResults.TDensity5.value = density(eval(document.FmResults.TDensityEval5.value),"\261");
        var objC1 = document.FmResults.TNeighbourObjC1.value;
        var objC2 = document.FmResults.TNeighbourObjC2.value;
        var average = app.getNeighboursCountAverageByColorCharacter(objC1,objC2);
        if (!isNaN(average)) { // number of such objects is 0
            document.FmResults.TNeighboursCountMin.value = app.getNeighboursCountMinByColorCharacter(objC1,objC2);
            document.FmResults.TNeighboursCountMax.value = app.getNeighboursCountMaxByColorCharacter(objC1,objC2);
            document.FmResults.TNeighboursCountAverage.value = app.sDouble(average,4);
            document.FmResults.TNeighboursCountAQD.value = app.sDouble(app.getNeighboursCountAQDByColorCharacter(objC1,objC2),4);
        } else {
            document.FmResults.TNeighboursCountMin.value = "n/a";
            document.FmResults.TNeighboursCountMax.value = "n/a";
            document.FmResults.TNeighboursCountAverage.value = "n/a";
            document.FmResults.TNeighboursCountAQD.value = "n/a";
        }
    }
    if (Ok && top.scenario != null) {
        setSettings(top.scenario);
        Ok = false;
        PageApply();
    }
    if (!Ok) {
        BlinkProgress(window.BlinkProgressState=!window.BlinkProgressState,app.isRunningProblem());
        setTimeout("onTimer()",2500);
    } else {
        window.BlinkProgressState=false;
        BlinkProgress(2,app.isRunningProblem());
        setTimeout("if (!window.BlinkProgressState) BlinkProgress(false,false)",3000);
        onTimerActive=false;
    }
    ExecuteDisabled=false;
}


