public class ProductOption extends BorderedPage {
	private static final long serialVersionUID = 1L;
	private static final Logger log = LoggerFactory.getLogger(ProductOption.class);
	private static final String PAGE_TITLE_CREATE = "Add Product Option";
	private DashboardSBBeanLocal dashboardSBBeanLocal = SessionBeanManager.getDashboardSBBeanLocal();
	private Form form = new Form("form");
	private com.farheap.jsi.utils.Constants.Option chosenOptionType;
	private final RegexField basePrice = new RegexField("basePrice", "Base Price", false);
	private final RegexField unitPrice = new RegexField("unitPrice", "Unit Price", false);
	private final Select optionValueSelect = new Select("optionValueSelect", "Option Value", false);
	private final Radio preflighRequiredRadioTrue = new Radio("true", "Yes");
	private final Radio preflighRequiredRadioFalse = new Radio("false", "No");
	private final Radio trappingRequiredRadioTrue = new Radio("true", "Yes");
	private final Radio trappingRequiredRadioFalse = new Radio("false", "No");
	private final Radio deliveryMailingServicesRadioTrue = new Radio("true", "Yes");
	private final Radio deliveryMailingServicesRadioFalse = new Radio("false", "No");
	private final Radio laminatingLaminatedRadioTrue = new Radio("true", "Yes");
	private final Radio laminatingLaminatedRadioFalse = new Radio("false", "No");
	private final Radio shapeCutOutRadioTrue = new Radio("true", "Yes");
	private final Radio shapeCutOutRadioFalse = new Radio("false", "No");
	private IntegerField amount = null;
	private TextField coverSubstrate = null;
	private IntegerField fullCoatedSurfaces = null;
	private IntegerField spotCoatedSurfaces = null;
	private IntegerField spotColors = null;
	private IntegerField deliveryRequiredDuration = null;
	private TextField deliveryMethod = null;
	private TextField deliveryServiceLevel = null;
	private IntegerField laminatingThickness = null;
	private IntegerField layoutPages = null;
	private IntegerField layoutFinishedDimensions = null;
	private TextField mediaFluting = null;
	private Select mediaFlutingDirectionSelect = null;
	private TextField mediaColor = null;
	private IntegerField mediaRecycledPercentage = null;
	private IntegerField mediaWeight = null;
	private IntegerField packingBoxedQuantity = null;
	private IntegerField packingWrappedQuantity = null;
	private TextField shapeMaterial = null;
	private final Select optionTypeSelect = new Select("optionTypeSelect", "Option Type", true);

	//Bindable variable id automatically have the value set by request parameters
	public Long productId;

	protected HiddenField hiddenProductId = new HiddenField("productId", Long.class);
	protected HiddenField fieldName = new HiddenField("fieldName", String[].class);

	public ProductOption() {
		optionTypeSelect.setMultiple(false);
		optionTypeSelect.setDefaultOption(Option.EMPTY_OPTION);
		form.add(optionTypeSelect);
		optionTypeSelect.setDataProvider(new DataProvider<Option>() {
			@Override
			public List<Option> getData() {
				List<Option> options = new ArrayList<Option>();
				for (com.farheap.jsi.utils.Constants.Option option : EnumSet.allOf(com.farheap.jsi.utils.Constants.Option.class)) {
					options.add(new Option(option.name(), option.getLabel()));
				}
				return options;
			}
		});

		
		// NB: when using form.submit() the submit button cannot be
		// called 'submit'. If it is, the browser is likely to throw a JS exception.
		// submit button is called 'save'.
		optionTypeSelect.setAttribute("onchange", "form.submit();");

		basePrice.setAttribute("onblur", "javascript:validatePriceField(\'form_basePrice\');");
		basePrice.setTextAlign("right");
		basePrice.setPattern(com.farheap.jsi.utils.Constants.PRICE_REGEX);
		
		unitPrice.setAttribute("onblur", "javascript:validatePriceField(\'form_unitPrice\');");
		unitPrice.setTextAlign("right");
		unitPrice.setPattern(com.farheap.jsi.utils.Constants.PRICE_REGEX);
		
		Submit saveButton = new Submit("save", "Save", this, "onSave");
		saveButton.addStyleClass("btn btn-primary");

		Button cancelButton = new Submit("cancel", "Cancel", this, "OnCancelLink");
		cancelButton.addStyleClass("btn btn-primary");

		form.setButtonAlign("right");
		form.add(basePrice);
		form.add(unitPrice);
		form.add(saveButton);
		form.add(cancelButton);
		form.add(hiddenProductId);
		//form.setValidate(false);
		addControl(form);
		ClickUtils.bind(form);
		return;

	}

	@Override
	public void onInit() {
		super.onInit();
		this.productId = Long.parseLong(getContext().getRequest().getParameter("productId"));
		hiddenProductId.setValueObject(productId);
		ClickUtils.bind(form);
		if (!StringUtils.isBlank(optionTypeSelect.getValue())) {
			populate();
		}
	}

	private void populate() {
		List<String> selectedValues = optionTypeSelect.getSelectedValues();
		String value = selectedValues.get(0);
		for (final com.farheap.jsi.utils.Constants.Option o : EnumSet.allOf(com.farheap.jsi.utils.Constants.Option.class)) {
			if (o.name().equals(value)) {
				chosenOptionType = o;
				if (o.getOptions().size() != 0) {
					optionValueSelect.setMultiple(false);
					optionValueSelect.setDefaultOption(Option.EMPTY_OPTION);
					optionValueSelect.setDataProvider(new DataProvider<Option>() {
						@Override
						public List<Option> getData() {
							List<Option> options = new ArrayList<Option>();
							for (OptionI option : o.getOptions()) {
								options.add(new Option(option.name(), option.getLabel()));
							}
							return options;
						}
					});
					form.add(optionValueSelect);
					fieldName.setValueObject(new String[]{"optionValueSelect"});
				} else if (chosenOptionType != null) {
					switch (chosenOptionType) {
					case ART_DELIVERY_PREFLIGHT:
						RadioGroup preflighRequiredRadioGroup = new RadioGroup("preflighRequiredRadioGroup", true);
						preflighRequiredRadioGroup.add(preflighRequiredRadioTrue);
						preflighRequiredRadioGroup.add(preflighRequiredRadioFalse);
						preflighRequiredRadioGroup.setVerticalLayout(false);
						form.add(preflighRequiredRadioGroup);
						fieldName.setValueObject(new String[]{"preflighRequiredRadioGroup"});
						break;
					case ART_DELIVERY_TRAPPING:
						RadioGroup trappingRequiredRadioGroup = new RadioGroup("trappingRequiredRadioGroup", true);
						trappingRequiredRadioGroup.add(trappingRequiredRadioTrue);
						trappingRequiredRadioGroup.add(trappingRequiredRadioFalse);
						trappingRequiredRadioGroup.setVerticalLayout(false);
						form.add(trappingRequiredRadioGroup);
						fieldName.setValueObject(new String[]{"trappingRequiredRadioGroup"});
						break;
					case AMOUNT:
						amount = new IntegerField("amount", true);
						form.add(amount);
						fieldName.setValueObject(new String[]{"amount"});
						break;
					case BINDING_COVER_SUBSTRATE:
						coverSubstrate = new TextField("coverSubstrate", true);
						form.add(coverSubstrate);
						fieldName.setValueObject(new String[]{"coverSubstrate"});
						break;
					case COLOR_INK_FULL_COATED_SURFACE:
						fullCoatedSurfaces = new IntegerField("fullCoatedSurfaces", true);
						form.add(fullCoatedSurfaces);
						fieldName.setValueObject(new String[]{"fullCoatedSurfaces"});
						break;
					case COLOR_INK_SPOT_COATED_SURFACE:
						spotCoatedSurfaces = new IntegerField("spotCoatedSurfaces", true);
						form.add(spotCoatedSurfaces);
						fieldName.setValueObject(new String[]{"spotCoatedSurfaces"});
						break;
					case COLOR_INK_SPOT_COLORS:
						spotColors = new IntegerField("spotColors", true);
						form.add(spotColors);
						fieldName.setValueObject(new String[]{"spotColors"});
						break;
					case DELIVERY_REQUIRED_DURATION:
						deliveryRequiredDuration = new IntegerField("deliveryRequiredDuration", true);
						form.add(deliveryRequiredDuration);
						fieldName.setValueObject(new String[]{"deliveryRequiredDuration"});
						break;
					case DELIVERY_METHOD:
						deliveryMethod = new TextField("deliveryMethod", true);
						form.add(deliveryMethod);
						fieldName.setValueObject(new String[]{"deliveryMethod"});
						break;
					case DELIVERY_SERVICE_LEVEL:
						deliveryServiceLevel = new TextField("deliveryServiceLevel", true);
						form.add(deliveryServiceLevel);
						fieldName.setValueObject(new String[]{"deliveryServiceLevel"});
						break;
					case DELIVERY_MAILING_SERVICES:
						RadioGroup deliveryMailingServicesRadioGroup = new RadioGroup("deliveryMailingServicesRadioGroup", true);
						deliveryMailingServicesRadioGroup.add(deliveryMailingServicesRadioTrue);
						deliveryMailingServicesRadioGroup.add(deliveryMailingServicesRadioFalse);
						deliveryMailingServicesRadioGroup.setVerticalLayout(false);
						form.add(deliveryMailingServicesRadioGroup);
						fieldName.setValueObject(new String[]{"deliveryMailingServicesRadioGroup"});
						break;
					case LAMINATING_LAMINATED:
						RadioGroup laminatingLaminatedRadioGroup = new RadioGroup("laminatingLaminatedRadioGroup", true);
						laminatingLaminatedRadioGroup.add(laminatingLaminatedRadioTrue);
						laminatingLaminatedRadioGroup.add(laminatingLaminatedRadioFalse);
						laminatingLaminatedRadioGroup.setVerticalLayout(false);
						form.add(laminatingLaminatedRadioGroup);
						fieldName.setValueObject(new String[]{"laminatingLaminatedRadioGroup"});
						break;
					case LAMINATING_THICKNESS:
						laminatingThickness = new IntegerField("laminatingThickness", true);
						form.add(laminatingThickness);
						fieldName.setValueObject(new String[]{"laminatingThickness"});
						break;
					case LAYOUT_PAGES:
						layoutPages = new IntegerField("layoutPages", true);
						form.add(layoutPages);
						fieldName.setValueObject(new String[]{"layoutPages"});
						break;
					case LAYOUT_FINISHED_DIMENSIONS:
						layoutFinishedDimensions = new IntegerField("layoutFinishedDimensions", true);
						form.add(layoutFinishedDimensions);
						fieldName.setValueObject(new String[]{"layoutFinishedDimensions"});
						break;
					case MEDIA_FLUTING:
						mediaFluting = new TextField("mediaFluting", true);
						Select mediaFlutingDirectionSelect = new Select("mediaFlutingDirectionSelect", true);
						mediaFlutingDirectionSelect.setMultiple(false);
						mediaFlutingDirectionSelect.setDefaultOption(Option.EMPTY_OPTION);
						mediaFlutingDirectionSelect.setDataProvider(new DataProvider<Option>() {
							@Override
							public List<Option> getData() {
								List<Option> options = new ArrayList<Option>();
								for (OptionI option : com.farheap.jsi.utils.Constants.Option.MEDIA_FLUTING_DIRECTION.getOptions()) {
									options.add(new Option(option.name(), option.getLabel()));
								}
								return options;
							}
						});
						form.add(mediaFluting);
						form.add(mediaFlutingDirectionSelect);
						fieldName.setValueObject(new String[]{"mediaFluting","mediaFlutingDirectionSelect"});
						break;
					case MEDIA_COLOR:
						mediaColor = new TextField("mediaColor", true);
						form.add(mediaColor);
						fieldName.setValueObject(new String[]{"mediaColor"});
						break;
					case MEDIA_RECYCLED:
						mediaRecycledPercentage = new IntegerField("mediaRecycledPercentage", true);
						form.add(mediaRecycledPercentage);
						fieldName.setValueObject(new String[]{"mediaRecycledPercentage"});
						break;
					case MEDIA_WEIGHT:
						mediaWeight = new IntegerField("mediaWeight", true);
						form.add(mediaWeight);
						fieldName.setValueObject(new String[]{"mediaWeight"});
						break;
					case PACKING_BOXED_QUANTITY:
						packingBoxedQuantity = new IntegerField("packingBoxedQuantity", true);
						form.add(packingBoxedQuantity);
						fieldName.setValueObject(new String[]{"packingBoxedQuantity"});
						break;
					case PACKING_WRAPPED_QUANTITY:
						packingWrappedQuantity = new IntegerField("packingWrappedQuantity", true);
						form.add(packingWrappedQuantity);
						fieldName.setValueObject(new String[]{"packingWrappedQuantity"});
						break;
					case SHAPE_CUT_OUT:
						RadioGroup shapeCutOutRadioGroup = new RadioGroup("shapeCutOutRadioGroup", true);
						shapeCutOutRadioGroup.add(shapeCutOutRadioTrue);
						shapeCutOutRadioGroup.add(shapeCutOutRadioFalse);
						shapeCutOutRadioGroup.setVerticalLayout(false);
						form.add(shapeCutOutRadioGroup);
						fieldName.setValueObject(new String[]{"shapeCutOutRadioGroup"});
						break;
					case SHAPE_MATERIAL:
						shapeMaterial = new TextField("shapeMaterial", true);
						form.add(shapeMaterial);
						fieldName.setValueObject(new String[]{"shapeMaterial"});
						break;
					default:
						break;
					}
				}
				break;
			}
		}
	}

	@Override
	public void onGet() {
		super.onGet();
	}

	public final boolean onSave() throws SystemException {
		try {
			if (form.isValid()) {
				if (productId == null) {
					throw new BusinessException("ProductId is null. Can't save product option");
				}
				ProductOptionEnt productOptionEnt = new ProductOptionEnt();
				productOptionEnt.setBasePrice(StringUtils.isBlank(basePrice.getValue()) ? null : new BigDecimal(basePrice.getValue()));
				productOptionEnt.setUnitPrice(StringUtils.isBlank(unitPrice.getValue()) ? null : new BigDecimal(unitPrice.getValue()));
				productOptionEnt.setOptionType(chosenOptionType);
				String value = getValue(chosenOptionType);
				productOptionEnt.setValue(value);
				dashboardSBBeanLocal.saveNewProductOption(productOptionEnt, productId);
				form.clearValues();
				String[] f = (String[]) fieldName.getValueObject();
				for (int i = 0; i < f.length; i++) {
					String string = f[i];
					form.removeField(string);
				}
			}
		} catch (Exception e) {
			log.error("Could not save product option.", e);
			addModel("error", e.getMessage() != null ? e.getMessage() : "");
			return false;
		} finally {
			hiddenProductId.setValueObject(productId);
		}
		return true;
	}

	private String getValue(com.farheap.jsi.utils.Constants.Option chosenOptionType) {
		String result = "";
		if (optionValueSelect != null && !optionValueSelect.getSelectedValues().isEmpty() && optionValueSelect.getSelectedValues().get(0) != null) {
			return (String) optionValueSelect.getSelectedValues().get(0);
		} else {
			switch (chosenOptionType) {
			case ART_DELIVERY_PREFLIGHT:
				Boolean preflight = Boolean.FALSE;
				if (preflighRequiredRadioTrue.isChecked()) {
					preflight = Boolean.TRUE;
				}
				result = preflight.toString();
				break;
			case ART_DELIVERY_TRAPPING:
				Boolean trapping = Boolean.FALSE;
				if (trappingRequiredRadioTrue.isChecked()) {
					trapping = Boolean.TRUE;
				}
				result = trapping.toString();
				break;
			case AMOUNT:
				result = amount.getValue();
				break;
			case BINDING_COVER_SUBSTRATE:
				result = coverSubstrate.getValue();
				break;
			case COLOR_INK_FULL_COATED_SURFACE:
				result = fullCoatedSurfaces.getValue();
				break;
			case COLOR_INK_SPOT_COATED_SURFACE:
				result = spotCoatedSurfaces.getValue();
				break;
			case COLOR_INK_SPOT_COLORS:
				result = spotColors.getValue();
				break;
			case DELIVERY_REQUIRED_DURATION:
				result = deliveryRequiredDuration.getValue();
				break;
			case DELIVERY_METHOD:
				result = deliveryMethod.getValue();
				break;
			case DELIVERY_SERVICE_LEVEL:
				result = deliveryServiceLevel.getValue();
				break;
			case DELIVERY_MAILING_SERVICES:
				preflight = Boolean.FALSE;
				if (deliveryMailingServicesRadioTrue.isChecked()) {
					preflight = Boolean.TRUE;
				}
				result = preflight.toString();
				break;
			case LAMINATING_LAMINATED:
				preflight = Boolean.FALSE;
				if (laminatingLaminatedRadioTrue.isChecked()) {
					preflight = Boolean.TRUE;
				}
				result = preflight.toString();
				break;
			case LAMINATING_THICKNESS:
				result = laminatingThickness.getValue();
				break;
			case LAYOUT_PAGES:
				result = layoutPages.getValue();
				break;
			case LAYOUT_FINISHED_DIMENSIONS:
				result = layoutFinishedDimensions.getValue();
				break;
			case MEDIA_FLUTING:
				result = mediaFluting.getValue();
				if (mediaFlutingDirectionSelect != null && !mediaFlutingDirectionSelect.getSelectedValues().isEmpty()
						&& mediaFlutingDirectionSelect.getSelectedValues().get(0) != null) {
					return (String) mediaFlutingDirectionSelect.getSelectedValues().get(0);
				}
				break;
			case MEDIA_COLOR:
				result = mediaColor.getValue();
				break;
			case MEDIA_RECYCLED:
				result = mediaRecycledPercentage.getValue();
				break;
			case MEDIA_WEIGHT:
				result = mediaWeight.getValue();
				break;
			case PACKING_BOXED_QUANTITY:
				result = packingBoxedQuantity.getValue();
				break;
			case PACKING_WRAPPED_QUANTITY:
				result = packingWrappedQuantity.getValue();
				break;
			case SHAPE_CUT_OUT:
				preflight = Boolean.FALSE;
				if (shapeCutOutRadioTrue.isChecked()) {
					preflight = Boolean.TRUE;
				}
				result = preflight.toString();
				break;
			case SHAPE_MATERIAL:
				result = shapeMaterial.getValue();
				break;
			default:
				break;
			}
		}
		return result;

	}

	@Override
	public final String getTitle() {
		return PAGE_TITLE_CREATE;
	}

	@Override
	public String getHelp() {
		return getContext().getRequest().getContextPath() + "/provider/product-option-help.htm";
	}

	public Long getProductId() {
		return productId;
	}
	
	public boolean OnCancelLink() {
		HashMap<String, String> m = new HashMap<String, String>();
		m.put("productId", "" + productId);
		setRedirect(EditProduct.class, m);
		productId = null;
		return true;
	}

}
