@Override
  public void refreshView(List<Exception> exceptions) {

    if (chartTarget.getHightlitedEventModel().getViewParamRoot() != null
        && chartTarget.isVisible()) {
      for (Exception exception : exceptions) {
        if (exception instanceof EventRefreshException) {
          String errorMessage =
              "Trends and calculators could not all be updated for "
                  + chartTarget.getHightlitedEventModel().getViewParamRoot().getFriendlyName()
                  + ".\n"
                  + "Check that date bounds are not out of range and that the appropriate quotations are available.\n"
                  + "Also keep in mind that some calculators need full OLHC and Volume in order to be calculated.";
          String addMessage = exceptions.toString();
          showPopupDialog(errorMessage, "Ok", addMessage, null);
          exceptions.clear();
          break;
        }
      }
    }

    if (evtDefChartingPopupMenu != null
        && !evtDefChartingPopupMenu.getSelectionShell().isDisposed()) {
      initEvtChartingPopup(false);
    }

    if (evtDefTrendPopupMenu != null && !evtDefTrendPopupMenu.getSelectionShell().isDisposed()) {
      initEvtDefTrendPopup(false);
    }
  }
  private void initEvtDefTrendPopup(Boolean activate) {

    Set<EventInfo> availEventDefs = EventDefinition.loadMaxPassPrefsEventInfo();
    ActionDialogAction disactivateAction =
        new ActionDialogAction() {

          @Override
          public void action(Control targetControl) {

            Stock viewStateParams = chartTarget.getHightlitedEventModel().getViewParamRoot();
            if (viewStateParams != null) {
              highLight(chartTarget.getHighligtedId(), viewStateParams, true);
            } else {
              if (chartTarget.getChartedEvtDefsTrends() != null
                  && !chartTarget.getChartedEvtDefsTrends().isEmpty()) {
                String errorMessage =
                    "You must select a share in the portfolio to display its analysis.";
                showPopupDialog(errorMessage, "Ok", null, null);
              }
            }
          }
        };

    if (evtDefTrendPopupMenu == null || evtDefTrendPopupMenu.getSelectionShell().isDisposed()) {

      evtDefTrendPopupMenu =
          new PopupMenu<EventInfo>(
              chartTarget,
              evtDefsTrendChartingBut,
              availEventDefs,
              chartTarget.getChartedEvtDefsTrends(),
              false,
              true,
              SWT.CHECK,
              null,
              disactivateAction,
              true);
      Rectangle parentBounds =
          chartTarget.getDisplay().map(chartTarget, null, chartTarget.getBounds());
      evtDefTrendPopupMenu.open(
          new Point(parentBounds.x + parentBounds.width, parentBounds.y + parentBounds.height / 2),
          true);

    } else {

      evtDefTrendPopupMenu.updateAction(
          availEventDefs, chartTarget.getChartedEvtDefsTrends(), null, disactivateAction, true);
      evtDefTrendPopupMenu.getSelectionShell().setVisible(true);
      if (activate) {
        evtDefTrendPopupMenu.getSelectionShell().setActive();
        evtDefTrendPopupMenu.getSelectionShell().setFocus();
      }
    }
  }
  @Override
  public void shutDownDisplay() {

    //		for (SlidingPortfolioShare slidingPortfolioShare : chartTarget.getCurrentTabShareList()) {
    //			slidingPortfolioShare.setDisplayOnChart(true);
    //		}

    if (evtDefChartingPopupMenu != null) evtDefChartingPopupMenu.getSelectionShell().dispose();
    if (evtDefTrendPopupMenu != null) evtDefTrendPopupMenu.getSelectionShell().dispose();

    chartTarget.getMainChartWraper().resetLineChart();
    chartTarget.getMainChartWraper().resetBarChart();
    chartTarget.getMainChartWraper().resetIndicChart();
  }
  private void initChartSettingsPopup(Boolean activatePopup) {

    try {

      boolean isIndicatorSelected =
          chartTarget.getChartedEvtDef() != null
              && !chartTarget.getChartedEvtDef().equals(EventDefinition.ZERO);
      boolean isEmptyOutputIndicator = false;
      boolean isClearInProgress = false;
      String errorMessage =
          "Only user defined calculators can be customised.\n"
              + "You must select one of your user defined calculators in '"
              + INDICATORSBUTTXT
              + "'\n"
              + "And wait for its calculation to finish before changing the display settings.\n"
              + "New calculators can be defined using the menu Events -> Customise and create calculators ...";

      if (isIndicatorSelected) {

        final Set<OutputDescr> availableOutputs = new TreeSet<OutputDescr>();
        final Set<OutputDescr> displayedOutputs = new TreeSet<OutputDescr>();

        try {
          availableOutputs.addAll(
              chartTarget.getChartedEvtDef().getEventDefDescriptor().allOutputs());
          displayedOutputs.addAll(
              chartTarget.getChartedEvtDef().getEventDefDescriptor().displayedOutputs());
        } catch (NoSuchElementException e) {
          // errorMessage = e.toString() + "\n\n" +errorMessage;
          isClearInProgress = true;
          LOGGER.warn(e);
        }

        if (!availableOutputs.isEmpty()) {

          ActionDialogAction disactivateAction =
              new ActionDialogAction() {

                @Override
                public void action(Control targetControl) {
                  for (OutputDescr outputDescr : availableOutputs) {
                    if (displayedOutputs.contains(outputDescr)) {
                      outputDescr.setDisplayOnChart(true);
                    } else {
                      outputDescr.setDisplayOnChart(false);
                    }
                  }
                  Stock viewStateParams = chartTarget.getHightlitedEventModel().getViewParamRoot();
                  highLight(chartTarget.getHighligtedId(), viewStateParams, true);
                }
              };

          if (chartSettingsPopup == null || chartSettingsPopup.getSelectionShell().isDisposed()) {
            chartSettingsPopup =
                new PopupMenu<OutputDescr>(
                    chartTarget,
                    indicSettings,
                    availableOutputs,
                    displayedOutputs,
                    false,
                    true,
                    SWT.CHECK,
                    null,
                    disactivateAction,
                    true);
            Rectangle parentBounds =
                chartTarget.getDisplay().map(chartTarget, null, chartTarget.getBounds());
            chartSettingsPopup.open(
                new Point(parentBounds.x + parentBounds.width, parentBounds.y), false);
          } else {
            chartSettingsPopup.updateAction(
                availableOutputs, displayedOutputs, null, disactivateAction, true);
            chartSettingsPopup.getSelectionShell().setVisible(true);
            if (activatePopup) {
              chartSettingsPopup.getSelectionShell().setActive();
              chartSettingsPopup.getSelectionShell().setFocus();
            }
          }

        } else {

          if (chartSettingsPopup != null && !chartSettingsPopup.getSelectionShell().isDisposed()) {
            chartSettingsPopup.getSelectionShell().dispose();
          }
          isEmptyOutputIndicator = true;
        }
      }

      if (!isIndicatorSelected || (!isClearInProgress && isEmptyOutputIndicator)) {
        showPopupDialog(
            "No calculator selected or No settings available for the selected calculator.",
            "Ok",
            errorMessage,
            null);
      }

    } catch (Exception e) {
      LOGGER.warn(e, e);
      showPopupDialog(e.getMessage(), "Ok", null, null);
    }
  }
  private void initEvtChartingPopup(Boolean activatePopup) {

    Set<EventInfo> availEventDefs =
        new HashSet<EventInfo>(EventDefinition.loadMaxPassPrefsEventInfo());
    availEventDefs.add(EventDefinition.ZERO);
    final Set<EventInfo> chartedEvtDefTmpSet = new HashSet<EventInfo>();
    chartedEvtDefTmpSet.add(chartTarget.getChartedEvtDef());

    ActionDialogAction action =
        new ActionDialogAction() {

          @Override
          public void action(Control targetControl) {

            Stock viewStateParams = chartTarget.getHightlitedEventModel().getViewParamRoot();
            if (!chartedEvtDefTmpSet.isEmpty()) {
              // changing evtdef selection
              chartTarget.setChartedEvtDef(chartedEvtDefTmpSet.iterator().next());
              // if stock selected, we update
              boolean stockSelected = viewStateParams != null;
              if (stockSelected) {
                highLight(chartTarget.getHighligtedId(), viewStateParams, true);
              } else {
                // warning only if evtdef selected and no stock
                if (chartTarget.getChartedEvtDef() != null
                    && !chartTarget.getChartedEvtDef().equals(EventDefinition.ZERO)) {
                  String errorMessage =
                      "You must select a share in the portfolio to display its analysis.";
                  showPopupDialog(errorMessage, "Ok", null, null);
                }
              }
            }
          }
        };

    if (evtDefChartingPopupMenu == null
        || evtDefChartingPopupMenu.getSelectionShell().isDisposed()) {

      evtDefChartingPopupMenu =
          new PopupMenu<EventInfo>(
              chartTarget,
              evtDefsChartingBut,
              availEventDefs,
              chartedEvtDefTmpSet,
              false,
              false,
              SWT.RADIO,
              action);
      Rectangle parentBounds =
          chartTarget.getDisplay().map(chartTarget, null, chartTarget.getBounds());
      evtDefChartingPopupMenu.open(
          new Point(parentBounds.x + parentBounds.width, parentBounds.y + parentBounds.height / 2),
          false);

    } else {

      evtDefChartingPopupMenu.updateAction(availEventDefs, chartedEvtDefTmpSet, action, null, null);
      evtDefChartingPopupMenu.getSelectionShell().setVisible(true);
      if (activatePopup) {
        evtDefChartingPopupMenu.getSelectionShell().setActive();
        evtDefChartingPopupMenu.getSelectionShell().setFocus();
      }
    }
  }
  private void updateChartIndicator(
      final Stock selectedShare, boolean recalculationGranted, boolean needsUpdate) {

    SortedMap<Date, double[]> outputCache =
        chartTarget
            .getHightlitedEventModel()
            .getOutputCache(selectedShare, chartTarget.getChartedEvtDef());

    if (outputCache == null || outputCache.isEmpty()) {

      // No indic found despite recalc
      if (!recalculationGranted && !needsUpdate) {
        String errMsg =
            "No output data are available for display within the period you have selected share "
                + selectedShare.getFriendlyName()
                + " and "
                + chartTarget.getChartedEvtDef().getEventReadableDef()
                + ".\n"
                + "If you just cleared the calculations results, you may want to Force and Update calculations.";
        String addMsg =
            "This may also happen if calculations failed, or if there is not enough quotations for the period.\n"
                +
                // "Check the calculators in "+TRENDBUTTXT+" as well as the date boundaries against
                // the available quotations.\n" +
                "You may want to check the date boundaries against the available quotations.\n"
                + "Also note that some calculators need full OLHC and Volume in order to be calculated.\n"
                + "If '"
                + chartTarget.getChartedEvtDef().getEventReadableDef()
                + "' is a calculator created by you, you may also want to check the formula.";
        showPopupDialog(errMsg, "Ok", addMsg, null);
      }

      // Thats all good, we display
    } else {

      SortedMap<Date, double[]> subMap = new TreeMap<Date, double[]>();
      if (!outputCache.isEmpty()) {

        Calendar instance = Calendar.getInstance();
        instance.setTime(chartTarget.getSlidingEndDate());
        QuotationsFactories.getFactory().incrementDate(instance, 1);
        Date endPlus1 = instance.getTime();

        if (endPlus1.after(outputCache.lastKey())) {
          subMap = outputCache.tailMap(this.chartTarget.getSlidingStartDate());
        } else {
          subMap = outputCache.subMap(this.chartTarget.getSlidingStartDate(), endPlus1);
        }

        if (!subMap.isEmpty())
          chartTarget
              .getMainChartWraper()
              .updateIndicDataSet(
                  chartTarget.getChartedEvtDef(), subMap, chartTarget.getPlotChartDimensions());
      }

      if (chartSettingsPopup != null && !chartSettingsPopup.getSelectionShell().isDisposed()) {
        initChartSettingsPopup(false);
      }
    }
  }
  @Override
  public void highLight(Integer idx, Stock selectedShare, Boolean recalculationGranted) {

    try {

      this.chartTarget.getShell().setEnabled(false);
      this.chartTarget.getParent().getParent().setCursor(CursorFactory.getCursor(SWT.CURSOR_WAIT));

      chartTarget.getMainChartWraper().setMainYAxisLabel("");
      if (idx == null || selectedShare == null) {
        return;
      }

      chartTarget.setHighligtedId(idx);
      chartTarget.getHightlitedEventModel().setViewParamRoot(selectedShare);

      if (chartTarget.isDisposed() || !chartTarget.isVisible()) {
        return;
      }

      if (!chartTarget.getChartedEvtDefsTrends().isEmpty()) {
        chartTarget.getMainChartWraper().resetBarChart();
      }
      if (!chartTarget.getChartedEvtDef().equals(EventDefinition.ZERO)) {
        chartTarget.getMainChartWraper().resetIndicChart();
      }

      hideAllButSelected(selectedShare);

      chartTarget.getMainChartWraper().setMainYAxisLabel(selectedShare.getFriendlyName());
      chartTarget.getMainChartWraper().highLightSerie(idx, 1);

      if (!chartTarget.getChartedEvtDefsTrends().isEmpty()
          || !chartTarget
              .getChartedEvtDef()
              .equals(EventDefinition.ZERO)) { // Some thing has to be displayed

        // We try and run
        try {
          Set<EventInfo> allEvtInfos = chartTarget.initChartedEvtDefsTrendsSet();
          allEvtInfos.addAll(chartTarget.getChartedEvtDefsTrends());
          if (!chartTarget.getChartedEvtDef().equals(EventDefinition.ZERO))
            allEvtInfos.add(chartTarget.getChartedEvtDef());

          HashSet<EventInfo> notUpToDateEventInfos = new HashSet<EventInfo>();
          Calendar minDate = Calendar.getInstance();
          minDate.setTime(new Date(0));
          Boolean needsUpdate =
              chartTarget
                  .getHightlitedEventModel()
                  .cacheNeedsUpdateCheck(
                      selectedShare,
                      chartTarget.getSlidingStartDate(),
                      chartTarget.getSlidingEndDate(),
                      notUpToDateEventInfos,
                      minDate,
                      allEvtInfos.toArray(new EventInfo[0]));

          if (needsUpdate) {
            eventsRecalculationAck(
                selectedShare,
                chartTarget.getSlidingStartDate(),
                chartTarget.getSlidingEndDate(),
                notUpToDateEventInfos,
                minDate);
          }

          if (!chartTarget.getChartedEvtDef().equals(EventDefinition.ZERO)) {
            updateChartIndicator(selectedShare, recalculationGranted, needsUpdate);
          } else {
            if (chartSettingsPopup != null
                && !chartSettingsPopup.getSelectionShell().isDisposed()) {
              chartSettingsPopup.getSelectionShell().dispose();
            }
          }

          if (!chartTarget.getChartedEvtDefsTrends().isEmpty()) {
            updateBarChart(
                selectedShare,
                chartTarget.getSlidingStartDate(),
                recalculationGranted,
                needsUpdate);
          }

        } catch (Exception e) {
          LOGGER.error(e, e);
        }
      }

      if (chartTarget.getChartedEvtDef() != null
          && chartTarget.getChartedEvtDef().equals(EventDefinition.ZERO))
        chartTarget.getMainChartWraper().resetIndicChart();
      if (chartTarget.getChartedEvtDefsTrends().isEmpty())
        chartTarget.getMainChartWraper().resetBarChart();

      if (chartTarget.getChartedEvtDefsTrends().isEmpty()
          && (chartTarget.getChartedEvtDef() == null
              || chartTarget.getChartedEvtDef().equals(EventDefinition.ZERO))) {
        String errorMessage =
            "No Calculator or Trend is selected.\n Use the buttons below the chart to select a calculator and trends.";
        showPopupDialog(errorMessage, "Ok", null, null);
      }

    } finally {

      this.chartTarget.getShell().setEnabled(true);
      this.chartTarget.getParent().getParent().setCursor(CursorFactory.getCursor(SWT.CURSOR_ARROW));
    }
  }