package controller;

import boundary.PlayerApplication;
import boundary.PlayerLevelView;

import java.awt.EventQueue;
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.swapInitiated(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();
      if(model.counter>0)
    	  model.counter--;
      // ends the level from here
      if(model.counter==0) {
      	EventQueue.invokeLater(new Runnable() {
  			@Override
  			public void run() {
  	            PlayerEndLevelCtrl end = new PlayerEndLevelCtrl(app, model);
  				end.endLevel();
  			}
      	});
      }
      ((PlayerLevelView)app.getView()).update();
    }
  }

  @Override
  public void mousePressed(MouseEvent event) {
    Point point;
    if (event.getButton() == MouseEvent.BUTTON1 &&
        model.playerState == PlayerState.NONE &&
        (point = identifyPoint(event)) != null) {
      startMoveCtrl.startMove(point);
    }
    ((PlayerLevelView)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) {
      if (point != null) {
    	expandMoveCtrl.expandMove(point);
      }
      else {
          model.playerState = PlayerState.NONE;
          model.move = new Move();
          if(model.counter>0)
        	  model.counter--;
          // ends the level from here
          if(model.counter==0) {
          	EventQueue.invokeLater(new Runnable() {
      			@Override
      			public void run() {
      	            PlayerEndLevelCtrl end = new PlayerEndLevelCtrl(app, model);
      				end.endLevel();
      			}
          	});
          }
          ((PlayerLevelView)app.getView()).update();
      }
    }
  }

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

@@ -1309,32 +1309,361 @@
 t.getY());%0A  %7D%0A%0A
+  protected void fizzleMove() %7B%0A    // make the move fizzle%0A    model.playerState = PlayerState.NONE;%0A    model.move = new Move();%0A    if (model.counter %3E 0) %7B%0A      model.counter--;%0A    %7D%0A%0A    // ends the level from here%0A    if (model.counter == 0) %7B%0A      EventQueue.invokeLater(new PlayerEndLevelCtrl(app, model));%0A    %7D%0A  %7D%0A%0A
   @Override%0A  pu
@@ -2116,17 +2116,16 @@
 nt) %7B%7D%0A%0A
-%0A
   @Overr
@@ -2235,400 +2235,21 @@
     
-model.playerState = PlayerState.NONE;%0A      model.move = new Move();%0A      if(model.counter%3E0)%0A    %09  model.counter--;%0A      // ends the level from here%0A      if(model.counter==0) %7B%0A      %09EventQueue.invokeLater(new Runnable() %7B%0A  %09%09%09@Override%0A  %09%09%09public void run() %7B%0A  %09            PlayerEndLevelCtrl end = new PlayerEndLevelCtrl(app, model);%0A  %09%09%09%09end.endLevel();%0A  %09%09%09%7D%0A      %09%7D);%0A      %7D
+fizzleMove();
 %0A   
@@ -2261,32 +2261,33 @@
 PlayerLevelView)
+ 
 app.getView()).u
@@ -2590,32 +2590,33 @@
 PlayerLevelView)
+ 
 app.getView()).r
@@ -2973,59 +2973,8 @@
 ) %7B%0A
-    Point point;%0A    point = identifyPoint(event);%0A
     
@@ -3030,546 +3030,150 @@
     
-if (point != null) %7B%0A    %09expandMoveCtrl.expandMove(point);%0A      %7D%0A      else %7B%0A          model.playerState = PlayerState.NONE;%0A          model.move = new Move();%0A          if(model.counter%3E0)%0A        %09  model.counter--;%0A          // ends the level from here%0A          if(model.counter==0) %7B%0A          %09EventQueue.invokeLater(new Runnable() %7B%0A      %09%09%09@Override%0A      %09%09%09public void run() %7B%0A      %09            PlayerEndLe
+Point point = identifyPoint(event);%0A      if (point != null) %7B%0A        expandMo
 ve
-l
 Ctrl
- end = new PlayerEndLevelCtrl(app, model);%0A      %09%09%09%09end.endLevel();%0A      %09%09%09%7D%0A          %09%7D);%0A          %7D%0A  
+.expandMove(point);%0A      %7D else %7B%0A        fizzleMove();%0A
     

Format and simplify PlayerBoardMouseCtrl