/*
   * (non-Javadoc)
   *
   * @see
   * si.vicos.annotations.editor.tracking.TrackingEditor.EditAssistant#editFrame
   * (si.vicos.annotations.editor.tracking.EditableAnnotatedSequence, int,
   * si.vicos.annotations.Annotation)
   */
  @Override
  public EditList editFrame(EditableAnnotatedSequence sequence, int frame, Annotation region) {

    EditList list = new EditList();

    try {

      list.add(new EditRegionOperation(frame, region));
      list.add(new EditTagAddOperation(frame, "keyframe"));

      // Interpolate forward if possible

      int last = 0;

      for (last = frame + 1; last < sequence.size(); last++)
        if (sequence.hasTag(last, "keyframe") && !sequence.get(last).isNull()) break;

      if (!(last == sequence.size() || frame > last - 2))
        list.addAll(interpolate(sequence, frame, region, last, sequence.get(frame)));

      // Interpolate backwards if possible

      int first = 0;

      for (first = frame - 1; first >= 0; first--)
        if (sequence.hasTag(first, "keyframe") && !sequence.get(first).isNull()) break;

      if (!(first == -1 || first > frame - 2))
        list.addAll(interpolate(sequence, first, sequence.get(first), frame, region));

    } catch (Exception e) {

      Application.getApplicationLogger().report(e);
    }

    return list;
  }
  /**
   * Instantiates a new tracking viewer.
   *
   * @param provider the provider
   */
  public TrackingViewer(ImagesProvider provider) {

    super("org.annotations.TrackingViewer", "Viewer");

    setLayout(new BorderLayout());

    this.provider = provider;

    this.model = new ViewerTreeModel();

    Settings settings =
        Application.getApplication().getSettingsManager().getSettings("aibu.viewer.ini");

    this.timeline = new Timeline(1, new PrefixProxySettings(settings, "timeline@"));
    this.timeline.getTrack("tags").addObject(model);

    this.values = new DefaultTreeModel(model);

    this.tree = new JTree(this.values);
    this.tree.setRootVisible(false);
    this.tree.setCellRenderer(new ViewerTreeCellRenderer());

    tree.addMouseListener(
        new MouseAdapter() {
          public void mousePressed(MouseEvent e) {
            int selRow = tree.getRowForLocation(e.getX(), e.getY());
            TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
            if (selRow != -1) {
              Object selected = selPath.getLastPathComponent();
              if (e.getClickCount() == 2
                  && selected instanceof ViewerTreeModel.AnnotationSource.ValuesAnnotations) {

                ViewerTreeModel.AnnotationSource.ValuesAnnotations value =
                    (ViewerTreeModel.AnnotationSource.ValuesAnnotations) selected;

                value.togglePlot();
              }
            }
          }
        });

    JSplitPane horizontalSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);

    horizontalSplit.setLeftComponent(panel);

    horizontalSplit.setRightComponent(new JScrollPane(this.tree));

    horizontalSplit.setResizeWeight(0.9);

    horizontalSplit.setDividerLocation(0.5);

    JSplitPane verticalSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);

    verticalSplit.setTopComponent(horizontalSplit);

    verticalSplit.setBottomComponent(timeline);

    verticalSplit.setResizeWeight(0.9);

    verticalSplit.setDividerLocation(0.8);

    add(verticalSplit, BorderLayout.CENTER);

    JToolBar menu = new JToolBar(JToolBar.HORIZONTAL);

    menu.setFloatable(false);

    menu.add(first);
    menu.add(previous);
    menu.add(next);
    menu.add(last);

    add(menu, BorderLayout.SOUTH);

    initKeyboardShortcuts();

    timeline.addTimelineListener(updater);

    timeline.setBorder(BorderFactory.createLoweredBevelBorder());

    timeline.setPosition(0);
    timeline.setToolTipText("test");

    setDropTarget(
        new DropTarget(
            this,
            DnDConstants.ACTION_COPY_OR_MOVE,
            new DropTargetAdapter() {

              @Override
              public void drop(DropTargetDropEvent event) {
                try {
                  Transferable tr = event.getTransferable();
                  Properties properties =
                      (Properties)
                          tr.getTransferData(TransferableAnnotations.ANNOTATIONS_PROPERTIES_FLAVOR);

                  String color = properties.getProperty("color");

                  Annotations annotations =
                      (Annotations) tr.getTransferData(TransferableAnnotations.ANNOTATIONS_FLAVOR);

                  String name = properties.getProperty("name");
                  String ancestry = properties.getProperty("ancestry");

                  if (!model.instances.isEmpty()
                      && !StringUtils.same(ancestry, model.getAncestry())) {
                    event.rejectDrop();
                    return;
                  }

                  if (annotations != null) {
                    event.acceptDrop(DnDConstants.ACTION_COPY);

                    add(name, annotations, color, ancestry);

                    event.dropComplete(true);
                    return;
                  }
                  event.rejectDrop();
                } catch (Exception e) {
                  e.printStackTrace();
                  event.rejectDrop();
                }
              }
            },
            true));
  }