package com.steering.pss.plnsaleord.lenthCal;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 重算方法类
 * @author TJG
 * @version v1.1
 * @date 2017.04.24
 */
public class CoreLenRecalCulation {
    /**
     * 圆周率
     */
    private static double Pi = 3.1415926; // 圆周率

    /**
     * 重算过程
     */
    public static LenCalculateOutObject recaComput(LenCalculateInObject param,
            Boolean flag) {
        LenCalculateOutObject paramOut = new LenCalculateOutObject();
        boolean shrt_stove = param.getShrtstove(); // 短尺随炉
        double sigl_len = 0;//param.getSigllen(); // 单倍尺长
        double burning = param.getBurning() / 100; // 烧损(%)
        List<Double> Diameter = param.getDiameter(); // 断面(管坯直径)集合
        double lengthmax = param.getLengthmax(); // 最大长度
        double lengthmin = param.getLengthmin(); // 最小长度
        double lengthmaxZg = param.getLengthmaxZg(); // 轧制转移最大长度
        double lengthminZg = param.getLengthminZg(); // 轧制转移最小长度
        double Cuthead_tail = param.getCutheadtail(); // 切头尾
        double Billetmax = param.getBilletmax(); // 元整或调整必须小于环形炉最长
        double Sizing = param.getSizing(); // 定径后max(m)
        double avg_len_min = 0; // 平均长度大于（m）
//        if (!param.getAvgLenMin().equals("")) {
            avg_len_min = param.getAvgLenMin();
//        }
        double chekJavl = 0; // 测量J值
//        if (!param.getCheckJVal().equals("")) {
            chekJavl = param.getCheckJVal();
//        }
        double aimlength = 0; // 目标长度
        int Cutnum = 0;
        double lossprcent = 0;
        boolean isOutput = true; // 是否能够生产
        String reason = ""; // 不可生产的原因
        double cutMat = param.getCutMax();// 最大分切数
//        double endlenSpe = param.getEndlenSpecstd();// 成品使用公差
        if (cutMat == 0) {
            cutMat = 100;
        }
        // 计算控制壁厚外径，及控制外径壁厚管单重
        LenCalculateOutObject lenCalOut1 = PlnControlOutWallTick
                .outWallTick(param);
        if (!lenCalOut1.getisOutput()) {
            isOutput = false;
            paramOut.setisOutput(isOutput);
            paramOut.setReason(lenCalOut1.getReason());
            return paramOut;
        }
        double weight_one = lenCalOut1.getMiGtWt();// 轧管管单重
        // #start 判断数据是否正常

        // 烧损率必须小于100%
        if (burning >= 1 || burning < 0) {
            isOutput = false;
            reason = "烧损率必须在0-99%之间！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }

        // 最大长度必须大于零
        if (lengthmax <= 0) {
            isOutput = false;
            reason = "最大长度必须大于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }

        // 最小长度必须大于等于零
        if (lengthmin < 0) {
            isOutput = false;
            reason = "最小长度必须大于等于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }

        // 轧制转移最大长度必须大于零
        if (lengthmaxZg <= 0) {
            isOutput = false;
            reason = "轧制转移最大长度必须大于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }

        // 轧制转移最小长度必须大于等于零
        if (lengthminZg < 0) {
            isOutput = false;
            reason = "轧制转移最小长度必须大于等于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }

        // 切头尾必须大于等于零
        if (Cuthead_tail < 0) {
            isOutput = false;
            reason = "切头尾必须大于等于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }
        else if (Cuthead_tail < 0.000001) {
            Cuthead_tail = 1;
        }

        // 环形炉最长必须大于零
        if (Billetmax <= 0) {
            isOutput = false;
            reason = "单倍坯长必须大于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }

        // 冷床长度必须大于零
        if (Sizing <= 0) {
            isOutput = false;
            reason = "冷床长度必须大于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }

        // 短尺最短必须大于等于零
        // if (Footmin < 0) {
        // isOutput = false;
        // reason = "短尺最短必须大于等于零！";
        // paramOut.setisOutput(isOutput);
        // paramOut.setReason(reason);
        // return paramOut;
        // }
        // #end

        // 坯料米单重
        double weightofm = 0;

        // 坯料重量
        double Billet_weight = 0;
        double lengthZzmax = 0;// 轧制长度
        double diame = 0;// 最佳断面
        // /循环断面集合，找出最佳断面
        for (int i = 0; i < Diameter.size(); i++) {
            diame = Diameter.get(i);

            // 坯料米单重
            weightofm = (7.8 * Pi / 4 * diame * diame) / 1000 / 1000;

            // 极限单倍坯重
            double billetweight = weightofm * (Billetmax / 1000);

            // 极限轧制长度
            lengthZzmax = billetweight * (1 - burning) / weight_one
                    + (1 - param.getTubeEndRatio()) * Cuthead_tail;
        }
        // 验证：轧制长度<冷床长度，否则单倍坯长调整无效
        if (lengthZzmax >= Sizing) {
            isOutput = false;
            reason = "轧制长度TZ大于等于冷长长度,单倍坯长圆整或调整无效，轧制长度TZ："
                    + new BigDecimal(lengthZzmax).setScale(3,
                            RoundingMode.HALF_UP).doubleValue() + "m,冷床长度："
                    + Sizing + "m！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }
        double tubeYuLong = 0;// 管余长
        if (lengthZzmax > 0) {
            // /分切过程
            // 1.无短尺随炉and无使用单倍长度
            if (!shrt_stove && sigl_len <= 0) {
                double x = (lengthZzmax - Cuthead_tail) / lengthmaxZg;
                double y = (lengthZzmax - Cuthead_tail) / lengthminZg;
                if (y > 0) {
                    // 获取最小整数
                    int min = CoreIsRounded.isRounded(x, y);
                    if (min != 0) {
                        Cutnum = min;
                        aimlength = (lengthZzmax - Cuthead_tail) / Cutnum;// 目标转移长度
                        tubeYuLong = 0;
                    }
                    else {
                        Cutnum = (int) (x);
                        if (Cutnum == 0) {
                            Cutnum = 1;
                        }
                        aimlength = lengthmaxZg; // 目标转移长度
                        // 管余长=(（轧制长度TZ -切头尾）/轧管转移长度上限-INT（轧制长度TZ
                        // -切头尾）/轧管转移长度上限+1）)* 轧管转移长度上限
                        tubeYuLong = lengthZzmax - Cutnum * aimlength
                                - Cuthead_tail;
                        // ((lengthZzmax - Cuthead_tail)
                        // / lengthmaxZg - (int) ((lengthZzmax - Cuthead_tail) /
                        // lengthmaxZg))
                        // * lengthmaxZg;
                    }
                }
                else {
                    isOutput = false;
                    java.text.DecimalFormat df = new java.text.DecimalFormat(
                            "#0.000");
                    reason = "轧管工序：轧制长度TZ" + df.format(lengthZzmax)
                            + "米、转移长度下限" + df.format(lengthminZg) + "米、切头尾"
                            + df.format(Cuthead_tail) + "米,无法生产！";
                    paramOut.setisOutput(isOutput);
                    paramOut.setReason(reason);
                    return paramOut;
                }
            }
            // 2.短尺随炉
            if (shrt_stove && sigl_len <= 0) {
                double x = (lengthZzmax - Cuthead_tail) / lengthmaxZg;
                double y = (lengthZzmax - Cuthead_tail) / lengthminZg;
                if (y > 0) {
                    // 获取最小整数
                    int min = CoreIsRounded.isRounded(x, y);
                    if (min != 0) {
                        Cutnum = min;
                        aimlength = (lengthZzmax - Cuthead_tail) / Cutnum;// 目标转移长度
                        tubeYuLong = 0;
                    }
                    else {
                        if (((((lengthZzmax - Cuthead_tail) / lengthminZg) - (int) ((lengthZzmax - Cuthead_tail) / lengthminZg)) * lengthminZg) >= 8.5) {
                            Cutnum = (int) (y) + 1;
                            aimlength = lengthminZg;
                            tubeYuLong = 0;
                        }
                        else {
                            Cutnum = (int) (x);
                            if (Cutnum == 0) {
                                Cutnum = 1;
                            }
                            aimlength = lengthmaxZg; // 目标转移长度
                            tubeYuLong = lengthZzmax - Cutnum * aimlength
                                    - Cuthead_tail;
                            // ((lengthZzmax - Cuthead_tail)
                            // / lengthmaxZg - (int) ((lengthZzmax -
                            // Cuthead_tail) / lengthmaxZg))
                            // * lengthmaxZg;
                        }
                    }
                }
                else {
                    isOutput = false;
                    java.text.DecimalFormat df = new java.text.DecimalFormat(
                            "#0.000");
                    reason = "轧管工序：轧制长度TZ" + df.format(lengthZzmax)
                            + "米，转移长度下限" + df.format(lengthminZg) + "米、切头尾"
                            + df.format(Cuthead_tail) + "米，无法生产！";
                    paramOut.setisOutput(isOutput);
                    paramOut.setReason(reason);
                    return paramOut;
                }

            }
            // 3.单倍尺长
            if (sigl_len > 0) {

                Cutnum = param.getCutnum();
                if (Cutnum == 0) {
                    Cutnum = 1;
                }
                aimlength = param.getAimlength();
                // 管余长=轧制长度TZ-分切*目标长度+切头尾
                tubeYuLong = lengthZzmax - Cutnum * aimlength - Cuthead_tail;
            }
//            if (tubeYuLong < 0) {
//                paramOut.setisOutput(false);
//                paramOut.setReason("管余长不能为负数："+tubeYuLong+",轧制长度TZ:"
//                        + new BigDecimal(lengthZzmax).setScale(3,
//                                RoundingMode.HALF_UP).doubleValue()
//                        + ",分切数:"
//                        + Cutnum
//                        + ",目标长度:"
//                        + new BigDecimal(aimlength).setScale(3,
//                                RoundingMode.HALF_UP).doubleValue() + "!");
//                return paramOut;
//            }
//            else {
                tubeYuLong = new BigDecimal(tubeYuLong).setScale(1,
                        RoundingMode.HALF_UP).doubleValue();
//            }
            // 坯调整
            double piStock = tubeYuLong * (weight_one * 1000)
                    / (7.8 * Pi * diame * diame / 4) / (1 - burning) * 1000
                    * 1000;
            // 验证1：管余长<>0，报警=“计算验证字段写“长度需调整””
            if (tubeYuLong != 0) {
                paramOut.setVerify1("管余长："
                        + new BigDecimal(tubeYuLong).setScale(1,
                                RoundingMode.HALF_UP).doubleValue()
                        + "m,坯调整:"
                        + new BigDecimal(piStock).setScale(0,
                                RoundingMode.HALF_UP).doubleValue() + "mm");
            }
            // 验证2：目标长度>平均长度 and 目标长度>转移长度下限+J值/1000 and
            // 分切<最大分切数and目标长度<=轧管转移长度上限
            if (aimlength >= avg_len_min
                    && aimlength >= lengthminZg + chekJavl / 1000
                    && Cutnum <= cutMat && aimlength <= lengthmaxZg) {
                paramOut.setVerify2("");
            }
            else {
                paramOut
                        .setVerify2("长度超出范围:目标长度("
                                + new BigDecimal(aimlength).setScale(2,
                                        RoundingMode.HALF_UP).doubleValue()
                                + "),平均长度("
                                + new BigDecimal(avg_len_min).setScale(2,
                                        RoundingMode.HALF_UP).doubleValue()
                                + "),转移长度下限("
                                + new BigDecimal(lengthminZg).setScale(2,
                                        RoundingMode.HALF_UP).doubleValue()
                                + "),转移长度上限("
                                + new BigDecimal(lengthmaxZg).setScale(2,
                                        RoundingMode.HALF_UP).doubleValue()
                                + "),J值("
                                + new BigDecimal(chekJavl / 1000).setScale(2,
                                        RoundingMode.HALF_UP).doubleValue()
                                + "),最大分切数("+cutMat+")");
            }

            // 管长度太短，无法分切
            if (Cutnum <= 0) {
                isOutput = false;
                java.text.DecimalFormat df = new java.text.DecimalFormat(
                        "#0.000");
                reason = "分切数为:" + Cutnum + "，无法分切！（轧制长度TZ"
                        + df.format(lengthZzmax) + "）";
                paramOut.setisOutput(isOutput);
                paramOut.setReason(reason);
                return paramOut;
            }
            // 推算管坯的单倍坯长
            // 坯单支重=(轧管管单重*（轧制长度-切头尾）+轧管管单重*管端增厚系数*切头尾)/ （1-烧损）
            Billet_weight = ((weight_one * (lengthZzmax - Cuthead_tail) + weight_one
                    * param.getTubeEndRatio() * Cuthead_tail) / (1 - burning));
        }
        else {
            isOutput = false;
            reason = "轧制长度必须大于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }

        double BefHotlength = 0;// 连轧后托管前的管长
        double BefHotdiameter = 0;// 连轧后托管前外径
        double BefHotWallthi = 0;// 连轧后托管前壁厚

        double diameter = 0;// 芯棒直径
        if (param.getDiameterMandrel().equals("")) {
            diameter = 0;
        }
        else {
            diameter = Double.parseDouble(param.getDiameterMandrel());
        }
        if (param.getPassMame().equals("")) {
            BefHotdiameter = 0;
        }
        else {
            BefHotdiameter = Double.parseDouble(param.getPassMame().substring(0, 3));
        }
        BefHotWallthi = (BefHotdiameter - diameter) / 2;
        BefHotlength = weight_one
                * lengthZzmax
                / ((0.02466 * BefHotWallthi * (BefHotdiameter - BefHotWallthi)) / 1000);
        // 验证3：轧制长度的炼轧最短，验证不改变原有计算结果
        // 如果是ASSEL机组 不比较
        if (!param.getPlineCode().trim().equals("C012")) {
            if (BefHotlength < param.getLengthMinTube()) {
                paramOut.setVerify3("连轧后长度:"
                        + new BigDecimal(BefHotlength).setScale(2,
                                RoundingMode.HALF_UP).doubleValue()
                        + "米,脱管机最短:" + param.getLengthMinTube() + "米,脱不出");
            }
        }
        paramOut.setAimoutdiameter(lenCalOut1.getAimoutdiameter());
        paramOut.setAimwallthick(Double.parseDouble(lenCalOut1
                .getAimwallthick()));
        paramOut.setAimlength(new BigDecimal(aimlength).setScale(2,
                RoundingMode.HALF_UP).doubleValue());
        paramOut.setCutnum(Cutnum);
        paramOut.setLengthZz(new BigDecimal(lengthZzmax).setScale(2,
                RoundingMode.HALF_UP).doubleValue());
        paramOut.setLossprcent(lossprcent);
        paramOut.setLengthLimit(new BigDecimal(lengthZzmax).setScale(2,
                RoundingMode.HALF_UP).doubleValue());
        paramOut.setBilletWeight(Billet_weight);
        paramOut.setBestDiame(diame);
        paramOut.setMiGtWt(weight_one);
        paramOut.setTubeYuLong(tubeYuLong);
        paramOut.setisOutput(isOutput);
        paramOut.setReason(reason);
        // paramOut
        return paramOut;
    }

    /**
     * 实现3舍4进
     * @param d
     * @return
     */
    public static double intThe(double d) {
        double i = 0;
        i = d + 0.001;
        BigDecimal bg = new BigDecimal(i).setScale(2, RoundingMode.HALF_UP);
        return bg.doubleValue();
    }

}