package com.gx.obe.management.dialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.eclipse.nebula.widgets.grid.Grid;
import org.eclipse.nebula.widgets.grid.GridColumn;
import org.eclipse.nebula.widgets.grid.GridItem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.core.MessageDialog;
import org.eclipse.swt.core.utils.GridUtils;
import org.eclipse.swt.core.widgets.EButton;
import org.eclipse.swt.core.widgets.EDialog;
import org.eclipse.swt.core.widgets.ELabel;
import org.eclipse.swt.core.widgets.ELink;
import org.eclipse.swt.core.widgets.ESepator;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

import com.gx.obe.ColorConstants;
import com.gx.obe.common.icons.IconsActivator;
import com.gx.obe.common.widget.thread.MyRunnable;
import com.gx.obe.common.widget.thread.SyncThread;
import com.gx.obe.components.core.Constants;
import com.gx.obe.components.core.I18NEnum;
import com.gx.obe.components.core.enumeration.EvaluationFactorEnum;
import com.gx.obe.http.json.JsonUtil;
import com.gx.obe.message.Messages;
import com.gx.obe.util.utils.BigDecimalUtils;
import com.gx.obe.util.utils.CollectionUtils;
import com.gx.obe.util.utils.ObjectUtils;
import com.gx.obe.web.entity.evaluation.EvaluationFactor;
import com.gx.obe.web.entity.tender.TenderProjectEntity;
import com.gx.obe.web.listener.WebBoolearListener;
import com.gx.obe.web.service.TenderProjectService;
import com.gx.obe.web.service.evaluation.EvaluationFactorService;
import com.gx.obe.web.service.evaluation.EvaluationStepService;
import com.gx.utils.ActionLogUtils;
import com.swtdesigner.ResourceManager;
import com.swtdesigner.SWTResourceManager;

/**
 * @Description: 批量应用价格得分公式界面
 * @author chenxw
 */
public class ApplyToOtherFactorComputerDialog extends EDialog {
	
	private Grid grid;
	private ELabel tipsLabel;
	private TenderProjectEntity tenderProject;
 //	private EvaluationStepService evaluationStepService = new EvaluationStepService();
//	private EvaluationFactorService evaluationFactorService = new EvaluationFactorService();
	private EButton applyToBtn;
	private Map<String, GridItem> gridItemMap;
	private String tenderPackName;
	private EvaluationFactor curFactor;
	private List<EvaluationFactor> evaluationFactorList;
	private ExecutorService executorService;
	
	private TenderProjectService tenderProjectService ;
	private EvaluationStepService evaluationStepService;
	private EvaluationFactorService evaluationFactorService ;
	/**
	 * Create the dialog.
	 * @param parentShell
	 * @param curFactor
	 */
	public ApplyToOtherFactorComputerDialog(Shell parentShell, TenderProjectEntity tenderProject, EvaluationFactor curFactor) {
		super(parentShell);
		this.setTitle("批量应用价格得分公式");
		
		this.tenderProject = tenderProject;
		this.curFactor = curFactor;
	}
	
	/**
	 * Create contents of the dialog.
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);
		container.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				if (null != executorService) executorService.shutdownNow();
			}
		});
		GridLayout gl_container = new GridLayout(1, false);
		gl_container.marginHeight = 0;
		gl_container.marginWidth = 0;
		container.setLayout(gl_container);
		
		Composite composite = new Composite(container, SWT.NONE);
		GridLayout gl_composite = new GridLayout(1, false);
		gl_composite.marginWidth = 0;
		gl_composite.marginHeight = 0;
		gl_composite.verticalSpacing = 0;
		composite.setLayout(gl_composite);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		
		Composite composite_1 = new Composite(composite, SWT.NONE);
		GridLayout gl_composite_1 = new GridLayout(1, false);
		gl_composite_1.verticalSpacing = 0;
		composite_1.setLayout(gl_composite_1);
		composite_1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		
		Composite opComposite = new Composite(composite_1, SWT.NONE);
		opComposite.setLayout(new GridLayout(3, false));
		opComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		
		ELink checkAllLink = new ELink(opComposite, SWT.NONE);
		checkAllLink.setText(Messages.Button_selectAll);
		checkAllLink.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/select_all.png"));
		checkAllLink.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				GridUtils.checkAll(grid, 0, true);
			}
		});
		
		ELink checkBackLink = new ELink(opComposite, SWT.NONE);
		checkBackLink.setText(Messages.Button_selectInvert);
		checkBackLink.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/switch.png"));
		checkBackLink.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				GridUtils.checkAllBack(grid, 0);
			}
		});
		
		ELink cancelLink = new ELink(opComposite, SWT.NONE);
		cancelLink.setText(Messages.Button_cancel);
		cancelLink.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/disselect_all.png"));
		cancelLink.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				GridUtils.checkAll(grid, 0, false);
			}
		});
		
		Composite composite_4 = new Composite(composite_1, SWT.NONE);
		GridLayout gl_composite_4 = new GridLayout(1, false);
		gl_composite_4.marginHeight = 0;
		gl_composite_4.marginWidth = 0;
		composite_4.setLayout(gl_composite_4);
		composite_4.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		
		grid = new Grid(composite_4, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		grid.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		grid.setHeaderVisible(true);
		grid.setAutoHeight(true);
		grid.setAutoWidth(true);
		grid.setItemHeight(Constants.ROW_HIGHT);
		grid.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				if (event.detail != SWT.CHECK) {
					GridItem item = (GridItem) event.item;
					item.setChecked(0, !item.getChecked(0));
				}
			}
		});
		
		GridColumn checkColumn = new GridColumn(grid, SWT.CHECK);
		checkColumn.setText("选择");
		checkColumn.setWidth(50);
		checkColumn.setMaxmumWidth(50);
		checkColumn.setAlignment(SWT.CENTER);
		
		GridColumn gridColumn_2 = new GridColumn(grid, SWT.NONE);
		gridColumn_2.setTree(true);
		gridColumn_2.setText("指标名称");
		gridColumn_2.setWidth(120);
		
		GridColumn gridColumn_3 = new GridColumn(grid, SWT.CENTER);
		gridColumn_3.setText("分值是否相同");
		gridColumn_3.setWidth(80);
		
		GridColumn gridColumn_4 = new GridColumn(grid, SWT.CENTER);
		gridColumn_4.setText("是否已设置公式");
		gridColumn_4.setWidth(80);
		
		
		ESepator sepator = new ESepator(composite, SWT.NONE);
		sepator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		sepator.setBackground(ColorConstants.SEP_LIGHT_COLOR);
		
		Composite composite_2 = new Composite(composite, SWT.NONE);
		composite_2.setLayout(new GridLayout(3, false));
		composite_2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		composite_2.setBackgroundMode(SWT.INHERIT_FORCE);
		composite_2.setBackgroundImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/fill_bg.png"));
		
		tipsLabel = new ELabel(composite_2, SWT.NONE);
		tipsLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		applyToBtn = new EButton(composite_2, SWT.NONE);
		applyToBtn.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				applyToAction();
			}
		});
		GridData gd_applyToBtn = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_applyToBtn.widthHint = 90;
		applyToBtn.setLayoutData(gd_applyToBtn);
		applyToBtn.setText(Messages.Button_confirm);
		
		EButton closeBtn = new EButton(composite_2, SWT.NONE);
		closeBtn.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				close();
			}
		});
		GridData gd_closeBtn = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_closeBtn.widthHint = 90;
		closeBtn.setLayoutData(gd_closeBtn);
		closeBtn.setText(Messages.Button_close);
		
		init();
		return container;
	}
	
	/**
	 * @Description: 初始化
	 * @author chenxw
	 */
	private void init() {
		grid.setTreeLinesVisible(false);
		tenderProjectService = new TenderProjectService();
		evaluationFactorService = new EvaluationFactorService();
		tenderPackName = com.gx.obe.components.core.I18N.getString(I18NEnum.SUBPACKAGE, tenderProject.getTenderType());
		tipsLabel.setText("将当前指标的价格得分公式复制到选中的其他指标。");
		
		new SyncThread(new SyncThread.Runnable() {
			public void run(){
				evaluationFactorList = evaluationFactorService.getAllEvaluationFactorList(tenderProject.getId(), EvaluationFactorEnum.AUDIT_PRICE);
				if (CollectionUtils.isNull(evaluationFactorList)) {
					evaluationFactorList = new ArrayList<EvaluationFactor>();
				}
				
				Display.getDefault().syncExec(new Runnable(){
					public void run(){
						initTenderPackGridAction();
					} 
				});
				
			}
		}).start();
	}
	
	
	/**
	 * @Description: 初始化标段列表
	 * @author chenxw
	 */
	private void initTenderPackGridAction() {
		if(null == grid || grid.isDisposed()){
			return;
		}
		gridItemMap = new HashMap<String, GridItem>();
		for(EvaluationFactor factor : evaluationFactorList){
			if (factor.getId().equals(curFactor.getId())){
				continue;
			} 
			GridItem gridItem = new GridItem(grid, SWT.NONE);
			initChildGridItem(factor, gridItem);
		}
	}
	
	/**
	 * @Description: 递归实现指标树
	 * @author guoyr
	 * @param factor
	 * @param parentGridItem
	 * @param selectId 
	 */
	private void initChildGridItem(EvaluationFactor factor, GridItem gridItem){
		gridItem.setChecked(0, false);
		gridItem.setCheckable(0, false);
		if(null != factor.getChildFactorList() && factor.getChildFactorList().size() > 0){
			for(EvaluationFactor childFactor : factor.getChildFactorList()){
				if (childFactor.getId().equals(curFactor.getId())){
					continue;
				} 
				GridItem childItem = new GridItem(gridItem, SWT.NONE);
				initChildGridItem(childFactor, childItem);
			}
			gridItem.setExpanded(true);
			gridItem.setText(1, ObjectUtils.getObjString(factor.getFactorName()));
			gridItem.setColumnSpan(1, 3);
			gridItem.setCheckVisible(0, false);
		}else {
			gridItem.setData("FACTOR_ID", factor.getId());
			gridItem.setText(1, ObjectUtils.getObjString(factor.getFactorName()));
			if (BigDecimalUtils.compareTo(curFactor.getFactorScore(), ObjectUtils.getObjBigDecimal(factor.getFactorScore())) == 0) {
				gridItem.setText(2, "是");
				gridItem.setChecked(0, true);
				gridItem.setCheckable(0, true);
				gridItem.setForeground(2, SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN));
			} else {
				gridItem.setText(2, "否");
				gridItem.setCheckable(0, false);
				gridItem.setForeground(2, SWTResourceManager.getColor(SWT.COLOR_RED));
			}
			if(null != factor.getComputerParams()) {
				gridItem.setForeground(3, SWTResourceManager.getColor(SWT.COLOR_RED));
			}
			gridItem.setText(3, null == factor.getComputerParams() ? "否" : "是");			
			gridItemMap.put(factor.getId(), gridItem);
		}
		
	}
	

	/**
	 * @Description: 确认
	 * @author chenxw 
	 */
	private void applyToAction() {
		if (!applyToBtn.getEnabled()) {
			return;
		}
		final List<String> factorIdList = GridUtils.getCheckedValues(grid, 0, "FACTOR_ID", true);
		if (factorIdList.isEmpty()) {
			MessageDialog.openShortMessage("请至少选择一个要应用的指标！");
			return;
		}
 
		
		executorService = Executors.newFixedThreadPool(factorIdList.size() > 5 ? 5 : factorIdList.size());
		ActionLogUtils.addServerLog(tenderProject.getId(),"将公式批量应用到其他指标", JsonUtil.jsonObjectToStr(factorIdList));
		for (final String factorId : factorIdList) {
			executorService.submit(new Runnable() {
				public void run() {
					EvaluationFactor factor = new EvaluationFactor();
					factor.setId(factorId);
					factor.setComputerParams(curFactor.getComputerParams());
					final boolean flag = evaluationFactorService.updateAssignProperty(factor, new String[] {"computerParams"});
						
					Display.getDefault().syncExec(new Runnable(){
						public void run(){
							GridItem gridItem = gridItemMap.get(factorId);
							if(null != gridItem && !gridItem.isDisposed()) {
								if (flag) {
									gridItem.setText(3, "是");
									gridItem.setChecked(0, false);
									gridItem.setCheckVisible(0, false);
									gridItem.setImage(0, ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/success.png"));
								}else {
									gridItem.setImage(0, ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/tray_close.png"));
								}
							}
						} 
					});
				}
			});
		}
		executorService.shutdown();
	 	
	}
	
	class ApplyToActionThread extends MyRunnable{
		private WebBoolearListener listener;
		private List<String> factorIdList;
		public ApplyToActionThread(List<String> factorIdList,WebBoolearListener listener){
			this.factorIdList = factorIdList;
			this.listener = listener;	
		}
		@Override
		public void run() {
			List<EvaluationFactor> priceFactorList = evaluationFactorService.findIds(factorIdList);
			if(priceFactorList == null){
				Display.getDefault().syncExec(new Runnable(){
					public void run(){
						MessageDialog.openError(getShell(), "应用失败！");						
					} 
				});
				return ;
			}
			for (EvaluationFactor priceFactor : priceFactorList) {
				priceFactor.setComputerParams(curFactor.getComputerParams());
			}
			ActionLogUtils.addServerLog(tenderProject.getId(),"将公式批量应用到其他标段", JsonUtil.jsonObjectToStr(factorIdList));
			boolean isUpdate = evaluationFactorService.batchUpdateProperty(priceFactorList, new String[] { "id","computerParams" });
 			listener.run(isUpdate);
		}
	}
	
	
	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(666, 470);
	}
	
}
