package com.gx.obe.evaluation.step.composite.clear;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.core.CallBack;
import org.eclipse.swt.core.utils.WidgetUtils;
import org.eclipse.swt.core.widgets.EButton;
import org.eclipse.swt.core.widgets.ECombo;
import org.eclipse.swt.core.widgets.ELink;
import org.eclipse.swt.core.widgets.ESepator;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ProgressBar;

import com.gx.obe.ColorConstants;
import com.gx.obe.DictValueEnum;
import com.gx.obe.common.icons.IconsActivator;
import com.gx.obe.common.widget.dialog.ProgressDialog;
import com.gx.obe.evaluation.step.checker.BaseChecker;
import com.gx.obe.evaluation.step.inter.BillCheckerCache;
import com.gx.obe.evaluation.step.inter.IBoqChecker;
import com.gx.obe.evaluation.step.inter.IChecker;
import com.gx.obe.util.utils.CollectionUtils;
import com.gx.obe.util.utils.LogUtils;
import com.gx.obe.util.utils.ObjectUtils;
import com.gx.obe.web.entity.CheckResult;
import com.gx.obe.web.entity.DictionaryValue;
import com.gx.obe.web.entity.Supplier;
import com.gx.obe.web.entity.boq.ConstructProject;
import com.gx.obe.web.entity.evaluation.EvaluationStep;
import com.gx.obe.web.entity.tender.TenderProjectEntity;
import com.gx.obe.web.service.CheckResultService;
import com.gx.obe.web.service.SupplierService;
import com.swtdesigner.ResourceManager;
import com.swtdesigner.SWTResourceManager;

/**
 * @Description:
 * @author guoyr
 */
public class BusinessClearTenderItemComposite extends Composite {
	
	private Logger LOG = Logger.getLogger(BusinessClearTenderItemComposite.class);
	
	private SupplierService supplierService = new SupplierService();
	private CheckResultService checkResultService = new CheckResultService();
	private TenderProjectEntity tenderProject;
	private EvaluationStep evaluationStep;
	private List<Supplier> supplierList;
	// 淡红色色
	private Composite staticComposite;
//	private Composite contentComposite;
	private Composite messageComposite;
	private CLabel messageLabel;
	private Composite cleanTenderResultComposite;
	private DictionaryValue dictionaryValue;
	private Composite cleanTenderDetailComposite;
	private List<IChecker> checkerList = new ArrayList<IChecker>();
	private StackLayout sl_staticComposite = new StackLayout();
	private Composite composite_supplier;
	private Composite detailLoadComposite;
	private ELink preSupplierBtn;
	private ELink nextSupplierBtn;
	private int curSupplierIndex = 0;
	private ECombo supplierCombo;
	private Button showErrorOnlyBtn;
	private EButton viewResultBtn;
	private IBoqChecker boqChecker;
	private BusinessClearTenderItemResultComposite businessClearTenderItemResultComposite;
	private CLabel errorNumLabel;
	private EButton refreshBtn;
	private String expertUserId;
	private List<CheckResult> checkResultList;
	private BillCheckerCache cacheListener;
	//ConstructProject 缓冲区
	private ExecutorService checkItemThreadPool;
	//当前供应商id集合
	private List<String> supplierIds;
	private int selection = 0;
	private Composite composite;
	private ProgressBar progressBar;
	private CallBack callBack;
	private boolean isStop = false;
	{
		LogUtils.logClass(BusinessClearTenderItemComposite.class);
	}
	
	/**
	 * Create the composite.
	 * 
	 * @param parent
	 * @param style
	 */
	public BusinessClearTenderItemComposite(Composite parent, int style) {
		super(parent, style);
		setLayout(new FillLayout(SWT.HORIZONTAL));
		tenderProject = (TenderProjectEntity) parent.getData("tenderProject");
		evaluationStep = (EvaluationStep) parent.getData("evaluationStep");
		dictionaryValue = (DictionaryValue) parent.getData("dictionaryValue");
		expertUserId = (String) parent.getData("expertUserId");
		
		staticComposite = new Composite(this, SWT.NONE);
		staticComposite.setLayout(sl_staticComposite);
		
		cleanTenderDetailComposite = new Composite(staticComposite, SWT.NONE);
		GridLayout gl_cleanTenderDetailComposite = new GridLayout(1, false);
		gl_cleanTenderDetailComposite.verticalSpacing = 0;
		gl_cleanTenderDetailComposite.marginHeight = 0;
		gl_cleanTenderDetailComposite.marginWidth = 0;
		cleanTenderDetailComposite.setLayout(gl_cleanTenderDetailComposite);
		
		composite_supplier = new Composite(cleanTenderDetailComposite, SWT.NONE);
		composite_supplier.setBackgroundMode(SWT.INHERIT_FORCE);
		GridLayout gl_composite_supplier = new GridLayout(7, false);
		composite_supplier.setLayout(gl_composite_supplier);
		composite_supplier.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		supplierCombo = new ECombo(composite_supplier, SWT.NONE);
		GridData gd_selectCaType_combo_combo = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_selectCaType_combo_combo.widthHint = 300;
		supplierCombo.setBorderColor(SWTResourceManager.getColor(60, 138, 226));
		supplierCombo.setLayoutData(gd_selectCaType_combo_combo);
		supplierCombo.setText("");
		supplierCombo.setHintText("--请选择供应商--");
		supplierCombo.setDownArrowImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/arrow_down_simp.png"));
		supplierCombo.addSelectionListener(new ECombo.ComboSelectoinListener() {
			@Override
			public void itemSelectoin(String name, Object value, int index) {
				selectSupplierAction();
			}
		});
		
		preSupplierBtn = new ELink(composite_supplier, SWT.NONE);
		preSupplierBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				viewNextSupplier(-1);
			}
		});
		preSupplierBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		preSupplierBtn.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/arrow_up.png"));
		preSupplierBtn.setText("上一家");
		
		nextSupplierBtn = new ELink(composite_supplier, SWT.NONE);
		nextSupplierBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				viewNextSupplier(1);
			}
		});
		nextSupplierBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		nextSupplierBtn.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/arrow_down.png"));
		nextSupplierBtn.setText("下一家");
		
		errorNumLabel = new CLabel(composite_supplier, SWT.NONE);
		errorNumLabel.setAlignment(SWT.CENTER);
		errorNumLabel.setFont(SWTResourceManager.getFont("微软雅黑", 10, SWT.NORMAL));
		errorNumLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		errorNumLabel.setText("");
		
		showErrorOnlyBtn = new Button(composite_supplier, SWT.CHECK);
		showErrorOnlyBtn.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				loadCheckDetail(null);
			}
		});
		showErrorOnlyBtn.setText("只显示错误项");
		
		refreshBtn = new EButton(composite_supplier, SWT.NONE);
		refreshBtn.setText("重新检查");
		refreshBtn.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/refresh.png"));
		refreshBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				startCleanTender(true, cacheListener);
			}
		});
		
		viewResultBtn = new EButton(composite_supplier, SWT.NONE);
		viewResultBtn.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				showResultComposite();
			}
		});
		viewResultBtn.setText("查看结果");
		viewResultBtn.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/view.png"));
		
		ESepator sep = new ESepator(cleanTenderDetailComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
		sep.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		sep.setBackground(ColorConstants.SEP_LIGHT_COLOR);
		
		detailLoadComposite = new Composite(cleanTenderDetailComposite, SWT.NONE);
		detailLoadComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
		detailLoadComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		
		cleanTenderResultComposite = new Composite(staticComposite, SWT.NONE);
		cleanTenderResultComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		messageComposite = new Composite(staticComposite, SWT.NONE);
		messageComposite.setLayout(new GridLayout(1, false));
		
		composite = new Composite(messageComposite, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1));
		composite.setLayout(new GridLayout(1, false));
		
		messageLabel = new CLabel(composite, SWT.NONE);
		messageLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));
		messageLabel.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/hourglass.png"));
		messageLabel.setFont(SWTResourceManager.getFont("微软雅黑", 20, SWT.BOLD));
		messageLabel.setForeground(ColorConstants.NOTE_TIPS_COLOR);
		messageLabel.setText("正在进行特征码检查，请稍等...");
		
		progressBar = new ProgressBar(composite, SWT.NONE);
		GridData gd_progressBar = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1);
		gd_progressBar.heightHint = 3;
		gd_progressBar.widthHint = 300;
		progressBar.setLayoutData(gd_progressBar);
		
		init();
	}
	
	/**
	 * @Description: 初始化
	 * @author guoyr
	 */
	private void init() {
		messageLabel.setText("正在进行" + dictionaryValue.getDictValueName() + "，请稍等...");
		supplierList = supplierService.getEvaluationStepSupplierList(tenderProject.getId(), evaluationStep);
		supplierCombo.removeAll();
		if (null == supplierList) {
			supplierList = new ArrayList<Supplier>();
		}
		for (Supplier supplier : supplierList) {
			supplierCombo.addItem(supplier.getSupplierName(), supplier);
		}
	}
	
	public static String formatTime(Long ms) {
		Integer ss = 1000;
		Integer mi = ss * 60;
		Integer hh = mi * 60;
		Integer dd = hh * 24;
		
		Long day = ms / dd;
		Long hour = (ms - day * dd) / hh;
		Long minute = (ms - day * dd - hour * hh) / mi;
		Long second = (ms - day * dd - hour * hh - minute * mi) / ss;
		Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;
		
		StringBuffer sb = new StringBuffer();
		if (day > 0) {
			sb.append(day + "天");
		}
		if (hour > 0) {
			sb.append(hour + "小时");
		}
		if (minute > 0) {
			sb.append(minute + "分");
		}
		if (second > 0) {
			sb.append(second + "秒");
		}
		if (milliSecond > 0) {
			sb.append(milliSecond + "毫秒");
		}
		return sb.toString();
	}
	
	/**
	 * @Description: 开始清标
	 * @author guoyr
	 */
	public void startCleanTender(final boolean newCheck, final BillCheckerCache billCheckerCache) {
		sl_staticComposite.topControl = messageComposite;
		this.cacheListener = billCheckerCache;
		staticComposite.layout();
		final boolean[] reCheckClear = new boolean[] { newCheck };
		// 启动清标线程	
		Thread drawKTableThread = new Thread(new Runnable() {
			public void run() {
//				long startTime=System.currentTimeMillis(); //获取开始时间
				if (!newCheck) {
					checkerList.clear();
					List<CheckResult> checkResults = checkResultService.getCheckResultByDictionaryValueId(tenderProject.getId(), dictionaryValue.getId(), null);
					if (null != checkResults && checkResults.size() >= supplierList.size()) {
						for (Supplier supplier : supplierList) {
							for (CheckResult checkResult : checkResults) {
								if (supplier.getId().equals(checkResult.getSupplierId())) {
									IChecker checker = BaseChecker.getCleanTenderChecker(tenderProject, supplier, evaluationStep, dictionaryValue, checkResult, null, billCheckerCache);
									checkerList.add(checker);
									break;
								}
							}
						}
					} else {
						// 清标结果与供应商数量不匹配，重新清标
						reCheckClear[0] = true;
					}
				}
				if (reCheckClear[0]) {
					//检查清标项结果
					checkItemAction();
				}
		
//				long endTime=System.currentTimeMillis(); //获取结束时间		
//				System.out.println("程序运行时间： "+ (endTime-startTime));
//				System.out.println("程序运行时间： "+formatTime(endTime-startTime));
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						if (null != cleanTenderResultComposite && !cleanTenderResultComposite.isDisposed()) {
							loadCheckResult();
						}
					}
				});
				if (null != callBack) {
					callBack.after();
				}
			}
		});
		drawKTableThread.start();
	}
	
	private synchronized void addSelection(int count) {
		selection += count;
	}
	
	/**
	 * @Description:
	 * @author mazc
	 */
	private void checkItemAction() {
		checkerList.clear();
		selection = 0;
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				if (!progressBar.isDisposed()) {
					progressBar.setMaximum(supplierList.size() * 3 + 10);
					progressBar.setSelection(0);
				}
			}
		});
		//线程池数量
		int iThreadNuber = 0;
		if (null != supplierList && supplierList.size() > 0) {
			//获取当前系统cup核数
			int iCpuNumber = Runtime.getRuntime().availableProcessors();
			//当前供应商数量大于iCpuNumber*2+1扩大线程池数量比便于调高效率 (2n + 1)
			if (supplierList.size() >= (iCpuNumber * 2 + 1)) {
				iThreadNuber = iCpuNumber * 2 + 1;
			} else {
				iThreadNuber = iCpuNumber - 1;
			}
			//根据系统当前cup数量计算线程数量
			iThreadNuber = supplierList.size() < iThreadNuber ? supplierList.size() : Math.max(2, iThreadNuber);
			//初始化checkResult
			checkResultList = new ArrayList<CheckResult>();
			supplierIds = new ArrayList<String>();
			for (final Supplier supplier : supplierList) {
				supplierIds.add(supplier.getId());
			}
			final CountDownLatch count = new CountDownLatch(supplierList.size());
			checkItemThreadPool = Executors.newFixedThreadPool(iThreadNuber);
			List<Future<IChecker>> checkResultFutureList = new ArrayList<Future<IChecker>>();
			final Runnable showStatusRunnable = new Runnable() {
				public void run() {
					if (!progressBar.isDisposed()) {
						progressBar.setSelection(selection);
					}
				}
			};
			for (final Supplier supplier : supplierList) {
				Callable<IChecker> run = new Callable<IChecker>() {
					public IChecker call() {
						addSelection(1);
						Display.getDefault().syncExec(showStatusRunnable);
						ConstructProject constructProject = cacheListener.getSupplierConstructProject(tenderProject.getId(), supplier.getId());
						addSelection(1);
						Display.getDefault().syncExec(showStatusRunnable);
						// 获得当前清标项的检查器，并对每家供应商进行清标
						IChecker checker = BaseChecker.getCleanTenderChecker(tenderProject, supplier, evaluationStep, dictionaryValue, null, constructProject, cacheListener);
						try {
							checker.startCheck(constructProject);
						} catch (Exception e) {
							LOG.error("清标失败！", e);
						}
						count.countDown();
						addSelection(1);
						Display.getDefault().syncExec(showStatusRunnable);
						return checker;
					}
				};
				// 在未来某个时间执行给定的命令
				checkResultFutureList.add(checkItemThreadPool.submit(run));
			}
			checkItemThreadPool.shutdown();
			
			for (Future<IChecker> future : checkResultFutureList) {
				try {
					IChecker checker = future.get();
					if (null != checker) {
						checkerList.add(checker);
						CheckResult checkResult = checker.getCheckResult();
						checkResult.setUserId(expertUserId);
						checkResultList.add(checkResult);
					}
				} catch (Exception e) {
					LOG.error("清标失败", e);
				}
			}
			if (CollectionUtils.isNull(checkResultList)) {
				return;
			}
			if (!isStop) {
				// 保存当前清标项的检查结果
				checkResultService.saveBoqCheckResult(tenderProject.getId(), expertUserId, dictionaryValue.getId(), checkResultList);
			}
			addSelection(10);
			Display.getDefault().syncExec(showStatusRunnable);
		}
	}
	
	/**
	 * @Description: 加载清标结果
	 * @author guoyr
	 * @param isRefresh
	 */
	private void loadCheckResult() {
		for (Control control : cleanTenderResultComposite.getChildren()) {
			control.dispose();
		}
		businessClearTenderItemResultComposite = new BusinessClearTenderItemResultComposite(cleanTenderResultComposite, SWT.NONE);
		GridLayout gridLayout = new GridLayout(1, false);
		gridLayout.marginHeight = 0;
		gridLayout.marginWidth = 0;
		gridLayout.verticalSpacing = 0;
		businessClearTenderItemResultComposite.setLayout(gridLayout);
		businessClearTenderItemResultComposite.showCheckResult(tenderProject, evaluationStep, dictionaryValue, checkerList);
		businessClearTenderItemResultComposite.addListener(new BusinessClearTenderItemResultComposite.ClickButtonListener() {
			public void loadDetail(IChecker checker) {
				loadCheckDetail(checker);
			}
			
			public void refresh(boolean is) {
				startCleanTender(is, cacheListener);
			}
			
		});
		showResultComposite();
	}
	
	/**
	 * @Description: 刷新表格的大小
	 * @author guoyr
	 */
	public void refreshTableSize() {
		if (null != businessClearTenderItemResultComposite && !businessClearTenderItemResultComposite.isDisposed()) {
			businessClearTenderItemResultComposite.refreshTableSize();
		}
		
	}
	
	/**
	 * @Description: 显示结果界面
	 * @author guoyr
	 */
	private void showResultComposite() {
		sl_staticComposite.topControl = cleanTenderResultComposite;
		cleanTenderResultComposite.layout();
		staticComposite.layout();
	}
	
	/**
	 * @Description: 加载详细检查情况
	 * @author guoyr
	 * @param supplier
	 */
	public void loadCheckDetail(Supplier supplier, CheckResult checkResult, BillCheckerCache billCheckerCache) {
		if (null == cacheListener) {
			cacheListener = billCheckerCache;
		}
		WidgetUtils.setControlVisible(refreshBtn, false);
		WidgetUtils.setControlVisible(viewResultBtn, false);
		int index = 0;
		for (Supplier s : supplierList) {
			if (supplier.getId().equals(s.getId())) {
				supplierCombo.select(index);
			}
			index++;
		}
		IChecker checker = BaseChecker.getCleanTenderChecker(tenderProject, supplier, evaluationStep, dictionaryValue, checkResult, null, cacheListener);
		loadCheckDetail(checker);
	}
	
	/**
	 * @Description: 加载详细检查情况
	 * @author guoyr
	 * @param supplier
	 */
	private void loadCheckDetail(IChecker checker) {
		if (null == supplierList || supplierList.size() == 0) {
			curSupplierIndex = 0;
			preSupplierBtn.setEnabled(false);
			nextSupplierBtn.setEnabled(false);
			return;
		}
		
		if (null != checker) {
			int curSupplierIndex = 0;
			for (Supplier s : supplierList) {
				if (s.getId().equals(checker.getSupplier().getId())) {
					supplierCombo.select(curSupplierIndex);
					break;
				}
				curSupplierIndex++;
			}
//			curSupplierIndex = checkerList.indexOf(checker);
			supplierCombo.select(curSupplierIndex);
		} else {
			curSupplierIndex = supplierCombo.getSelectionIndex();
			if (curSupplierIndex < 0) {
				curSupplierIndex = 0;
			}
			checker = checkerList.get(curSupplierIndex);
		}
		
		if (curSupplierIndex == 0) {
			if (checkerList.size() == 1) {
				nextSupplierBtn.setEnabled(false);
			}
			preSupplierBtn.setEnabled(false);
		} else {
			if (curSupplierIndex == checkerList.size() - 1) {
				nextSupplierBtn.setEnabled(false);
			} else {
				nextSupplierBtn.setEnabled(true);
			}
			preSupplierBtn.setEnabled(true);
		}
		
		final StringBuilder message = new StringBuilder();
		showErrorOnlyBtn.setEnabled(false);
		// 算术性错误检查
		if (DictValueEnum.CleanTender.ARITHMETIC_ERROR.equals(dictionaryValue.getDictValueCode())) {
			
			if (null == boqChecker) {
				boqChecker = new ArithmeticErrorItemListComposite(detailLoadComposite, SWT.NONE);
			}
			String calculationError = evaluationStep.getEvaluationParamByKey(EvaluationStep.CALCULATION_ERROR);
			// 如果是根据差额率来计算
			if (ObjectUtils.equals(calculationError, EvaluationStep.CALCULATION_ERROR_RATE)) {
				BigDecimal rate = evaluationStep.getEvaluationParamByKey(EvaluationStep.CALCULATION_ERROR_RATE, BigDecimal.class);
				if (null == rate || rate.compareTo(BigDecimal.ZERO) == 0) {
					rate = BigDecimal.valueOf(5);
				}
				message.append("差额率超过[±");
				message.append(rate);
				message.append("%]为算术错误。");
			} else {
				BigDecimal value = evaluationStep.getEvaluationParamByKey(EvaluationStep.CALCULATION_ERROR_VALUE, BigDecimal.class);
				if (null == value || value.compareTo(BigDecimal.ZERO) == 0) {
					value = BigDecimal.valueOf(20);
				}
				message.append("差额超过[±");
				message.append(value);
				message.append("]元为算术错误。");
			}
			
		} else if (DictValueEnum.CleanTender.ERROR_LEAK.equals(dictionaryValue.getDictValueCode())) {
			// 错漏项检查
			if (null == boqChecker) {
				boqChecker = new ErrorLeakItemListComposite(detailLoadComposite, SWT.NONE);
			}
		} else if (DictValueEnum.CleanTender.GUIFEI_RATE_CHECK.equals(dictionaryValue.getDictValueCode())) {
			
			// 规费检查
			if (null == boqChecker) {
				boqChecker = new RatesCompeteItemListComposite(detailLoadComposite, SWT.NONE);
			}
		} else if (DictValueEnum.CleanTender.AQWMSGF_RATE_CHECK.equals(dictionaryValue.getDictValueCode())) {
			// 安全文明施工费检查
			if (null == boqChecker) {
				
				boqChecker = new RatesCompeteItemListComposite(detailLoadComposite, SWT.NONE);
			}
		} else if (DictValueEnum.CleanTender.TAX_RATE_CHECK.equals(dictionaryValue.getDictValueCode())) {
			// 税金费率检查
			if (null == boqChecker) {
				boqChecker = new TaxFeesListComposite(detailLoadComposite, SWT.NONE);
			}
			
		} else if (DictValueEnum.CleanTender.UNCOMPETE_CHECK.equals(dictionaryValue.getDictValueCode())) {
			// 不可竞争费检查
			if (null == boqChecker) {
				boqChecker = new UnCompeteItemListComposite(detailLoadComposite, SWT.NONE);
			}
		} else if (DictValueEnum.CleanTender.INVENTORY_PRICE.equals(dictionaryValue.getDictValueCode())) {
			// 清单报价检查
			if (null == boqChecker) {
				boqChecker = new InventoryPriceItemListComposite(detailLoadComposite, SWT.NONE);
			}
			
			BigDecimal priceRateMaxRate = evaluationStep.getEvaluationParamByKey(EvaluationStep.MAX_DIFFERENCE_RATE, BigDecimal.class);
			if (null == priceRateMaxRate || priceRateMaxRate.compareTo(BigDecimal.ZERO) <= 0) {
				priceRateMaxRate = BigDecimal.valueOf(25);
			}
			BigDecimal priceRateMinRate = evaluationStep.getEvaluationParamByKey(EvaluationStep.MIN_DIFFERENCE_RATE, BigDecimal.class);
			if (null == priceRateMinRate || priceRateMinRate.compareTo(BigDecimal.ZERO) >= 0) {
				priceRateMinRate = BigDecimal.valueOf(-25);
			}
			message.append("差额率大于[");
			message.append(priceRateMaxRate);
			message.append("%]为过高，小于[");
			message.append(priceRateMinRate);
			message.append("%]为过低。");
			
		} else if (DictValueEnum.CleanTender.MATERIAL_PRICE.equals(dictionaryValue.getDictValueCode())) {
			// 材料报价检查
			if (null == boqChecker) {
				boqChecker = new MaterialPriceItemListComposite(detailLoadComposite, SWT.NONE);
			}
			
			BigDecimal priceRateMaxRate = evaluationStep.getEvaluationParamByKey(EvaluationStep.MAX_DIFFERENCE_RATE, BigDecimal.class);
			if (null == priceRateMaxRate || priceRateMaxRate.compareTo(BigDecimal.ZERO) <= 0) {
				priceRateMaxRate = BigDecimal.valueOf(25);
			}
			BigDecimal priceRateMinRate = evaluationStep.getEvaluationParamByKey(EvaluationStep.MIN_DIFFERENCE_RATE, BigDecimal.class);
			if (null == priceRateMinRate || priceRateMinRate.compareTo(BigDecimal.ZERO) >= 0) {
				priceRateMinRate = BigDecimal.valueOf(-25);
			}
			message.append("差额率大于±");
			message.append(priceRateMaxRate);
			message.append("%为过高，小于");
			message.append(priceRateMinRate);
			message.append("%为过低。");
		}
		String errors = "";
		if (null != checker.getCheckResult()) {
			if (checker.getCheckResult().getErrorNum() > 0) {
				errors = "共[" + checker.getCheckResult().getErrorNum() + "]处错误。  ";
			} else {
				errors = "无错误。 ";
			}
		}
		
		if (showErrorOnlyBtn.getSelection()) {
			boqChecker.listErrorOnlyCheckDetail(checker);
		} else {
			boqChecker.listCheckDetail(checker);
		}
		errorNumLabel.setText(message.toString() + "   " + errors);
		sl_staticComposite.topControl = cleanTenderDetailComposite;
		detailLoadComposite.layout();
		staticComposite.layout();
		if (null != boqChecker) {
			if (checker.getCheckResultDetailTreeList().size() == 0) {
				final IChecker newChecker = checker;
				
				final ProgressDialog synchShell = new ProgressDialog(getShell(), "正在进行" + newChecker.getDictionaryValue().getDictValueName() + "...");
				new Thread(new Runnable() {
					public void run() {
						ConstructProject constructProject = cacheListener.getSupplierConstructProject(tenderProject.getId(), newChecker.getSupplier().getId());
						try {
							newChecker.startCheck(constructProject);
						} catch (Exception e) {
							LOG.error("", e);
						}
						Display.getDefault().syncExec(new Runnable() {
							public void run() {
								if (!errorNumLabel.isDisposed()) {
									synchShell.close();
									showErrorOnlyBtn.setEnabled(true);
									if (newChecker.getErrorCount() > 0) {
										showErrorOnlyBtn.setEnabled(true);
										errorNumLabel.setText(message.toString() + "   共[" + newChecker.getErrorCount() + "]处错误。  ");
									} else {
										errorNumLabel.setText(message.toString() + "   无错误。   ");
										showErrorOnlyBtn.setEnabled(false);
									}
									if (showErrorOnlyBtn.getSelection()) {
										boqChecker.listErrorOnlyCheckDetail(newChecker);
									} else {
										boqChecker.listCheckDetail(newChecker);
									}
								}
							}
						});
					}
				}).start();
				synchShell.open();
			} else {
				showErrorOnlyBtn.setEnabled(true);
			}
		}
	}
	
	/**
	 * @Description: 选择供应商
	 * @author guoyr
	 */
	private void selectSupplierAction() {
		curSupplierIndex = supplierCombo.getSelectionIndex();
		loadCheckDetail(checkerList.get(curSupplierIndex));
	}
	
	/**
	 * @Description: 上一家或下一家
	 * @author guoyr
	 * @param preOrNext
	 */
	private void viewNextSupplier(int preOrNext) {
		if (curSupplierIndex + preOrNext >= 0 && curSupplierIndex + preOrNext < checkerList.size()) {
			if (preOrNext > 0 && nextSupplierBtn.getEnabled()) {
				loadCheckDetail(checkerList.get(curSupplierIndex + preOrNext));
			} else if (preSupplierBtn.getEnabled()) {
				loadCheckDetail(checkerList.get(curSupplierIndex + preOrNext));
			}
		}
	}
	
	public void addCallBack(CallBack callBack) {
		this.callBack = callBack;
	}
	
	@Override
	public void dispose() {
		if (null != checkItemThreadPool) {
			checkItemThreadPool.shutdownNow();
		}
		if (null != checkerList && checkerList.size() > 0) {
			for (IChecker checker : checkerList) {
				checker.stopCheck();
			}
		}
		isStop = true;
		super.dispose();
	}
	
	protected void checkSubclass() {}
}
