package controller;

import boundary.PlayerApplication;
import boundary.PlayerLevelView;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import model.Move;
import model.PlayerModel;
import model.PlayerState;
import model.Point;

/**
 * @author Eli Skeggs, Nick Chaput
 *
 * TODO: implement "Swap" special move, add validity checks to basic moves
 */
public class PlayerBoardMouseCtrl implements MouseListener, MouseMotionListener
{
  PlayerApplication app;
  PlayerModel model;

  PlayerRemoveCtrl removeCtrl;
  PlayerSwapCtrl swapCtrl;

  PlayerExpandMoveCtrl expandMoveCtrl;
  PlayerFinishMoveCtrl finishMoveCtrl;
  PlayerStartMoveCtrl startMoveCtrl;

  public PlayerBoardMouseCtrl(PlayerApplication app, PlayerModel model) {
    this.app = app;
    this.model = model;

    removeCtrl = new PlayerRemoveCtrl(app, model);
    swapCtrl = new PlayerSwapCtrl(app, model);

    expandMoveCtrl = new PlayerExpandMoveCtrl(app, model);
    finishMoveCtrl = new PlayerFinishMoveCtrl(app, model);
    startMoveCtrl = new PlayerStartMoveCtrl(app, model);
  }

  Point identifyPoint(MouseEvent event) {
    PlayerLevelView view = (PlayerLevelView) app.getView();
    return view.boardView.identifyPoint(event.getX(), event.getY());
  }

  @Override
  public void mouseClicked(MouseEvent event) {
    Point point;
    if (event.getButton() != MouseEvent.BUTTON1 ||
        (point = identifyPoint(event)) == null) {
      return;
    }

    switch (model.playerState) {
    case REMOVE:
      removeCtrl.mouseClicked(point);
      break;
    case SWAP:
      swapCtrl.mouseClicked(point);
      break;
    default:
      // do nothing!
    }
  }

  @Override
  public void mouseEntered(MouseEvent event) {}


  @Override
  public void mouseExited(MouseEvent event) {
    if (model.playerState == PlayerState.SELECT) {
      model.playerState = PlayerState.NONE;
      model.move = new Move();
      app.getView().repaint();
    }
  }

  @Override
  public void mousePressed(MouseEvent event) {
    Point point;
    if (event.getButton() == MouseEvent.BUTTON1 &&
        model.playerState == PlayerState.NONE &&
        (point = identifyPoint(event)) != null) {
      startMoveCtrl.startMove(point);
      model.counter--;
      app.getView().repaint();
    }
  }

  @Override
  public void mouseReleased(MouseEvent event) {
    Point point;
    if (event.getButton() == MouseEvent.BUTTON1 &&
        model.playerState == PlayerState.SELECT &&
        (point = identifyPoint(event)) != null) {
      finishMoveCtrl.finishMove(point);
    }
  }

  @Override
  public void mouseDragged(MouseEvent event) {
    Point point;
    point = identifyPoint(event);
    if (model.playerState == PlayerState.SELECT && point != null) {
      expandMoveCtrl.expandMove(point);
    }
    else {
        model.playerState = PlayerState.NONE;
        model.move = new Move();
        model.counter--;
        app.getView().repaint();
    }
  }

  @Override
  public void mouseMoved(MouseEvent event) {}
}

@@ -1941,32 +1941,73 @@
 w Move();%0A      
+model.counter--;%0A      ((PlayerLevelView)
 app.getView().re
@@ -1999,32 +1999,32 @@
 pp.getView()
-.repaint
+).update
 ();%0A    %7D%0A  
@@ -2298,33 +2298,32 @@
     
-  model.counter--;%0A      
+%7D%0A    ((PlayerLevelView)
 app.
@@ -2323,32 +2323,33 @@
 ew)app.getView()
+)
 .repaint();%0A    
@@ -2336,38 +2336,32 @@
 w()).repaint();%0A
-    %7D%0A
   %7D%0A%0A  @Override
@@ -2790,12 +2790,22 @@
 LECT
- && 
+) %7B%0A      if (
 poin
@@ -2821,18 +2821,17 @@
 ) %7B%0A    
-  
+%09
 expandMo
@@ -2864,21 +2864,27 @@
     
+  
 %7D%0A    
+  
 else %7B%0A
+  
     
@@ -2929,24 +2929,26 @@
 NE;%0A        
+  
 model.move =
@@ -2956,24 +2956,26 @@
 new Move();%0A
+  
         mode
@@ -2995,16 +2995,36 @@
         
+  ((PlayerLevelView)
 app.getV
@@ -3028,27 +3028,35 @@
 etView()
-.repaint();
+).update();%0A      %7D
 %0A    %7D%0A 

Fix counter decrementing as you drag and counter not updating