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 CoreLenCalculate {
    /**
     * 圆周率
     */
    private static double Pi = 3.1415926; // 圆周率

    /**
     * 计算过程
     */
    public static LenCalculateOutObject comput(LenCalculateInObject param,
            Boolean flag) {
        LenCalculateOutObject paramOut = new LenCalculateOutObject();
        boolean shrt_stove = param.getShrtstove(); // 短尺随炉
        double sigl_len = 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(); // 环形炉最长(mm)
        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 lengthZz = 0;
        double lengthLimit = 0; // 管极限长度(m)
        double Billet = 0; // 单倍坯长
        boolean isOutput = true; // 是否能够生产
        String reason = ""; // 不可生产的原因
        double BestDiame = 0; // 最佳断面（mm）
        double cutMat = param.getCutMax();// 最大分切数
        // double endlenSpe = param.getEndlenSpecstd();// 成品使用公差
        double lossprcent = 0;
        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;

        // 有无比冷床长度小的管极限长度。
        boolean isSmallerSize = false;
        double lengthZzmax = 0;// 极限轧制长度Sj
        // /循环断面集合，找出最佳断面
        for (int i = 0; i < Diameter.size(); i++) {
            double 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 > 0 && Sizing >= lengthZzmax) {
                isSmallerSize = true;
                lengthLimit = lengthZzmax;
            }
        }

        // /如果没有比冷床长度小的管极限长度。
        if (!isSmallerSize) {
            lengthLimit = Sizing;
        }

        if (lengthLimit > 0) {
            // /分切过程
            // 1.无短尺随炉and无使用单倍长度
            if (!shrt_stove && sigl_len <= 0) {
                int x = (int) ((lengthLimit - Cuthead_tail) / lengthmaxZg);
                int y = (int) ((lengthLimit - Cuthead_tail) / lengthminZg);
                // if (y > 0) {
                int z = y - x;
                if (y < 1 && x < 1) {
                    z = 1;
                }
                if (z >= 1) {
                    Cutnum = x + 1;
                    lengthZz = lengthLimit;
                    aimlength = (lengthZz - Cuthead_tail) / Cutnum;// 目标转移长度
                }
                else {
                    Cutnum = x;
                    lengthZz = Cutnum * lengthmaxZg + Cuthead_tail;
                    aimlength = lengthmaxZg; // 目标转移长度
                }
                // }
                // else {
                // Cutnum = 1;
                // lengthZz = Cutnum * lengthmaxZg + Cuthead_tail;
                // aimlength = lengthmaxZg; // 目标转移长度
                // isOutput = false;
                // java.text.DecimalFormat df = new java.text.DecimalFormat(
                // "#0.000");
                // reason = "轧管工序：管极限长度" + df.format(lengthLimit) +
                // "米、转移长度下限"
                // + df.format(lengthminZg) + "米、切头尾"
                // + df.format(Cuthead_tail) + "米,无法生产！";
                // paramOut.setisOutput(isOutput);
                // paramOut.setReason(reason);
                // return paramOut;
                // }
                // 验证：目标长度<平均长度 or 目标长度<转移长度下限+J值/1000
                if (aimlength < avg_len_min
                        || aimlength < lengthminZg + chekJavl / 1000) {
                    if (Cutnum - 1 == 0) {
                        Cutnum = 1;
                        aimlength = lengthZz - Cuthead_tail;// 目标转移长度
                    }
                    else {
                        Cutnum = Cutnum - 1;
                        aimlength = lengthmaxZg;// 目标转移长度
                    }
                    lengthZz = Cutnum * aimlength + Cuthead_tail;
                }
                // 验证：分切>最大分切数
                if (Cutnum > cutMat) {
                    Cutnum = (int) cutMat;
                    aimlength = lengthmaxZg;// 目标转移长度
                    lengthZz = Cutnum * lengthmaxZg + Cuthead_tail;
                }
                if (Cutnum == 0) {
                    isOutput = false;
                    reason = "分切数不能为0，按合同要求无法生产！";
                    paramOut.setisOutput(isOutput);
                    paramOut.setReason(reason);
                    return paramOut;
                }
            }
            // 2.短尺随炉
            if (shrt_stove && sigl_len <= 0) {
                int x = (int) ((lengthLimit - Cuthead_tail) / lengthmaxZg);
                int y = (int) ((lengthLimit - Cuthead_tail) / lengthminZg);
                // if (y > 0) {
                int z = y - x;
                if (y < 1 && x < 1) {
                    z = 1;
                }
                if (z >= 1) {
                    Cutnum = x + 1;
                    lengthZz = lengthLimit;
                    aimlength = (lengthZz - Cuthead_tail) / Cutnum; // 目标转移长度
                }
                else {
                    if (((((lengthLimit - Cuthead_tail) / lengthminZg) - y) * lengthminZg) >= 8.5) {
                        Cutnum = y + 1;
                        lengthZz = lengthLimit;
                        aimlength = lengthminZg;
                    }
                    else {
                        Cutnum = x;
                        lengthZz = Cutnum * lengthmaxZg + Cuthead_tail;
                        aimlength = lengthmaxZg; // 目标转移长度
                    }
                }
                // }
                // else {
                // Cutnum = 1;
                // lengthZz = Cutnum * lengthmaxZg + Cuthead_tail;
                // aimlength = lengthmaxZg; // 目标转移长度
                // isOutput = false;
                // java.text.DecimalFormat df = new java.text.DecimalFormat(
                // "#0.000");
                // reason = "轧管工序：管极限长度" + df.format(lengthLimit) +
                // "米，转移长度下限"
                // + df.format(lengthminZg) + "米、切头尾"
                // + df.format(Cuthead_tail) + "米，无法生产！";
                // paramOut.setisOutput(isOutput);
                // paramOut.setReason(reason);
                // return paramOut;
                // }

                // 验证：目标长度<平均长度 or 目标长度<转移长度下限+J值/1000
                if (aimlength < avg_len_min
                        || aimlength < lengthminZg + chekJavl / 1000) {
                    if (Cutnum - 1 == 0) {
                        Cutnum = 1;
                        aimlength = lengthZz - Cuthead_tail;// 目标转移长度
                    }
                    else {
                        Cutnum = Cutnum - 1;
                        aimlength = lengthmaxZg;// 目标转移长度
                    }
                    lengthZz = Cutnum * aimlength + Cuthead_tail;
                }
                // 验证：分切>最大分切数
                if (Cutnum > cutMat) {
                    Cutnum = (int) cutMat;
                    aimlength = lengthmaxZg;// 目标转移长度
                    lengthZz = Cutnum * lengthmaxZg + Cuthead_tail;
                }

            }
            // 3.单倍尺长
            if (sigl_len > 0) {
                int w = 0; // 有多少种分切方案
                if (param.getFootmin() > 0) {
                    w = (int)((lengthmax / sigl_len)+0.00001)
                            -(int)((lengthmin / sigl_len)+0.00001);
                }
                else {
                    w = (int) ((lengthmax / sigl_len)+0.00001)
                            - (int) ((lengthmin / sigl_len)+0.00001) - 1;
                    if (w < 0) {
                        w = 0;
                    }
                }
                if (w >= 0) {
                    int iNum = 0;
                    double result = 0;
                    double nLenght = 0;
                    for (int i = 0; i <= w; i++) {

                        // 极限轧制长度/（轧管转移长度上限-使用单倍长度* i
                        // +成品使用公差））*（轧管转移长度上限-使用单倍长度* i +成品使用公差
                        result = (int) ((lengthLimit - Cuthead_tail) / (lengthmaxZg - sigl_len
                                * i))
                                * (lengthmaxZg - sigl_len * i);
                        if (nLenght < result) {
                            nLenght = result;
                            iNum = i;
                        }
                    }
                    // 极限轧制长度/（轧管转移长度上限-使用单倍长度* i +成品使用公差）
                    Cutnum = (int) new BigDecimal(nLenght
                            / (lengthmaxZg - sigl_len * iNum)).setScale(2,
                            RoundingMode.HALF_UP).doubleValue();
                    if (Cutnum == 0) {
                        Cutnum = 1;
                    }
                    aimlength = lengthmaxZg - sigl_len * iNum;// 目标转移长度
                    if ((aimlength < lengthminZg || aimlength > lengthmaxZg)
                            && iNum > 1) {
                        iNum = iNum - 1;
                        if(iNum<0){
                            iNum=0;
                        }
                    }
                    
                    aimlength = lengthmaxZg - sigl_len * iNum;// 目标转移长度
                    lengthZz = Cutnum * aimlength + Cuthead_tail;

                    if (Cutnum > cutMat) {
                        Cutnum = (int) cutMat;
                        aimlength = lengthmaxZg - sigl_len * iNum;// 目标转移长度
                        lengthZz = Cutnum * aimlength + Cuthead_tail;
                    }
                }
            }
            // 管长度太短，无法分切
            if (Cutnum <= 0) {
                isOutput = false;
                java.text.DecimalFormat df = new java.text.DecimalFormat(
                        "#0.000");
                reason = "管长度太短，无法分切！（管极限长度" + df.format(lengthLimit) + "）";
                paramOut.setisOutput(isOutput);
                paramOut.setReason(reason);
                return paramOut;
            }
            // 推算管坯的单倍坯长
            // 坯单支重=(轧管管单重*（轧制长度-切头尾）+轧管管单重*管端增厚系数*切头尾)/ （1-烧损）
            Billet_weight = ((weight_one * (lengthZz - Cuthead_tail) + weight_one
                    * param.getTubeEndRatio() * Cuthead_tail) / (1 - burning));
            if (sigl_len > 0) {
                // 单倍坯长 =int((坯单支重/坯单重)/10)*10
                Billet = 10 * Math
                        .ceil((Billet_weight / weightofm) * 1000 / 10);
            }
            else {
                Billet = 10 * Math
                        .floor((Billet_weight / weightofm) * 1000 / 10);
            }
            // /损失率
            lossprcent = (lengthLimit - lengthZz) / lengthLimit * 100;
        }
        else {
            isOutput = false;
            reason = "管长度必须大于零！";
            paramOut.setisOutput(isOutput);
            paramOut.setReason(reason);
            return paramOut;
        }
        paramOut.setLossprcent(lossprcent);
        paramOut.setAimoutdiameter(lenCalOut1.getAimoutdiameter());
        paramOut.setAimwallthick(Double.parseDouble(lenCalOut1
                .getAimwallthick()));
        paramOut.setAimlength(aimlength);
        paramOut.setCutnum(Cutnum);
        paramOut.setLengthZz(lengthZz);
        paramOut.setLengthLimit(lengthLimit);
        paramOut.setBillet(Billet);
        paramOut.setBilletWeight(Billet_weight);
        paramOut.setBestDiame(BestDiame);
        paramOut.setMiGtWt(weight_one);
        paramOut.setisOutput(isOutput);
        paramOut.setReason(reason);
        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();
    }

}