package controllers
import play.api._
import play.api.i18n._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import controllers.services._
import models.services._
import forms._
import beans._
import org.squeryl._
import org.squeryl.PrimitiveTypeMode._
import org.squeryl.annotations.Column
import scala.collection.mutable.ArrayBuffer
import models.PartRelation

object DesignChangeController extends Controller{
   val Home = Redirect(routes.DesignChangeController.list(0,""))
   val Home2 = Redirect(routes.PartsListController.index(0,0,"",""))

   val designChangeRegistForm = Form(
      mapping(
          "dcNo" -> nonEmptyText,
          "dcDescription" -> nonEmptyText
       )(DesignChangeForm.apply)(DesignChangeForm.unapply)
  )
  
   val designChangeRelationRegistForm = Form(
       mapping(
            "partsListBeanBefore" -> mapping(
                "parent" -> text,
                "child" -> text,
                "quantity" -> longNumber,
                "relationKey" -> text
                )(PartsListBean.apply)(PartsListBean.unapply),
              "partsListBeanAfter" -> mapping(
                  "parent" -> nonEmptyText,
                  "child" -> text,
                  "quantity" -> longNumber,
                  "relationKey" -> text
                  )(PartsListBean.apply)(PartsListBean.unapply),
            "dcno" -> nonEmptyText
         )(DesignChangeRelationForm.apply)(DesignChangeRelationForm.unapply)
     )

  
  def create = Action { implicit request =>
    Ok(views.html.createDesignChangeForm(designChangeRegistForm))
  }
  
  def designChangeCoverRegistration() = Action { implicit request =>
    designChangeRegistForm.bindFromRequest.fold(
        formWithErrors => BadRequest(views.html.createDesignChangeForm(formWithErrors)),
        designChange => {
          inTransaction {
            DesignChangeManager().insert(designChange)
          }
   	    	  Home.flashing("success" -> "Design Change %s has been created".format(designChange.dcNo))       
        }
     )
  }
  
  def designChangeCoverModify(designChangeId: Long, dcSeq: Long, message: String) = Action { implicit request =>
    inTransaction {
      var partBuffer = ArrayBuffer[PartsListBean]()
      val designChange = DesignChangeManager().getById(designChangeId)
      val designChangeForm = DesignChangeForm(designChange.dcNo, designChange.dcDescription)
      val designChangeBuffer = DesignChangeManager().getDesinChangeInformation(designChange)
      if(dcSeq != 0) {
        val delRelation = designChange.delPartRelation.where(pr => pr.dcSeq === dcSeq).head
        for(returnPartBuffer <- PartRecursion().up(delRelation.child.head, 1)) {
          partBuffer += returnPartBuffer
        }
      }
      Ok(views.html.updateDesignChangeForm(designChangeRegistForm.fill(designChangeForm), designChangeId, designChangeBuffer, designChange.addPartRelation, partBuffer, dcSeq, message))
    }
  }

  def designChangeCoverModification(id: Long) = Action{ implicit request =>
    designChangeRegistForm.bindFromRequest.fold(
        formWithErrors => BadRequest(views.html.updateDesignChangeForm(formWithErrors, id, null, null, null, 0, null)),
        designChange => {
          inTransaction {
            DesignChangeManager().update(id, designChange)
          }
      	  Home.flashing("success" -> "Design Change %s has been created".format(designChange.dcNo))       
        }
    )
  }
  
  def list(page: Int, key: String) = Action { implicit request =>
    inTransaction {
      val row = Integer.decode(Messages("list.row"))
      val buff = DesignChangeManager().list(key)
      Ok(views.html.designchangelist(buff.page(page*row, row), buff.size, key, page))
    }
  }
  
  def designChangeCancel(id: Long) = Action { 
    inTransaction {
      DesignChangeManager().designChangeCancel(id)
      Redirect(routes.DesignChangeController.designChangeCoverModify(id, 0, ""))
     }
  }
  
  def designChangeCancelByLine(designChangeId: Long, delParentName: String, delChildName: String, addParentName: String, addChildName: String) = Action {
    inTransaction {
      val designChange = DesignChangeManager().getById(designChangeId)
      if(!delParentName.isEmpty()) {
        val delParent = PartManager().getByName(delParentName)
        val delChild = PartManager().getByName(delChildName)
        val cancelDelRelation = designChange.delPartRelation.where(pr => pr.parentId === delParent.id and pr.childId === delChild.id).head
        DesignChangeManager().designChangeDelCancelBySeq(designChangeId, cancelDelRelation.dcSeq)
      }
      if(!addParentName.isEmpty()) {
        val addParent = PartManager().getByName(addParentName)
        val addChild = PartManager().getByName(addChildName)
        val cancelAddRelation = designChange.addPartRelation.where(pr => pr.parentId === addParent.id and pr.childId === addChild.id).head
        DesignChangeManager().designChangeAddCancelBySeq(designChangeId, cancelAddRelation.dcSeq)
      }
    }
    Redirect(routes.DesignChangeController.designChangeCoverModify(designChangeId, 0, ""))    
  }
  
  def designChangeForm(parentName:String, childName:String, relationKey:String) = Action { implicit request =>
    inTransaction {
      var designChangeRelationForm = DesignChangeRelationForm(null, null, "")
       // 設計変更追加の場合、変更前の上位品番はセットしない。
      if(childName.isEmpty()) {
        designChangeRelationForm = DesignChangeRelationForm(generatePartsListBean("", childName, relationKey), generatePartsListBean(parentName, childName, relationKey), "")
      } else {
        designChangeRelationForm = DesignChangeRelationForm(generatePartsListBean(parentName, childName, relationKey), generatePartsListBean(parentName, childName, relationKey), "")
       }
      Ok(views.html.designChangeRelationForm(designChangeRelationRegistForm.fill(designChangeRelationForm), ""))
      }
	}

	def designChange() = Action { implicit request =>
	  designChangeRelationRegistForm.bindFromRequest.fold(
	      formWithErrors => BadRequest(views.html.designChangeRelationForm(formWithErrors, "")),
	      data => {
	    	  inTransaction {
	    	    val message= DesignChangeManager().designChange(data)
	    	    if(message == null) {
	    	      Home2.flashing("success" -> "Relation %s has been changed".format(data.partsListBeanBefore.parent + "/" + data.partsListBeanBefore.child))
	    	    } else {
	    	      Ok(views.html.designChangeRelationForm(designChangeRelationRegistForm.fill(data), message))
	    	    }
	    	  }
	      }
	  )
	}

  def designChangeAppend(designChangeId: Long, dcSeq: Long, targetParentName: String) = Action {
    inTransaction {
      val designChange = DesignChangeManager().getById(designChangeId)
      val delRelation =designChange.delPartRelation.where(pr => pr.dcSeq === dcSeq).head 
      val addRelation =designChange.addPartRelation.where(pr => pr.dcSeq === dcSeq).head 
      val delPart = delRelation.child.head
      val addPart = addRelation.child.head
      val ParentPart = PartManager().getByName(targetParentName)
      val delPartsListBean = PartsListBean(ParentPart.name, delPart.name, delRelation.quantity, delRelation.relationKey)
      val addPartsListBean = PartsListBean(ParentPart.name, addPart.name, addRelation.quantity, addRelation.relationKey)
      val data = DesignChangeRelationForm(delPartsListBean, addPartsListBean, designChange.dcNo)
      val message = DesignChangeManager().designChange(data)
      if(message == null) {
        Redirect(routes.DesignChangeController.designChangeCoverModify(designChangeId, dcSeq, ""))
      } else {
        Redirect(routes.DesignChangeController.designChangeCoverModify(designChangeId, dcSeq, message))
      }
    }
  }
  
  def designChangeRealtionModify(designChangeId: Long, dcDelSeq: Long, dcAddSeq: Long) = Action { implicit request =>
    inTransaction {
       var targetDelRelation = PartRelation(0, 0, 0, "", 0, 0, 0)
       var targetAddRelation = PartRelation(0, 0, 0, "", 0, 0, 0)
       var delParentNo = ""
       var delChildNo = ""
       var delRelationKey = ""
       var addParentNo = ""
       var addChildNo = ""
       var addRelationKey = ""
    	val designChange = DesignChangeManager().getById(designChangeId)
    	if(dcDelSeq != 0) {
    		targetDelRelation = designChange.delPartRelation.where(pr => pr.dcSeq === dcDelSeq).head
    		delParentNo = targetDelRelation.parent.head.name
    		delChildNo = targetDelRelation.child.head.name
    		delRelationKey = targetDelRelation.relationKey
    	}
    	if(dcAddSeq != 0) {
    		targetAddRelation = designChange.addPartRelation.where(pr => pr.dcSeq === dcAddSeq).head
    		addParentNo = targetAddRelation.parent.head.name
    		addChildNo = targetAddRelation.child.head.name
    		addRelationKey = targetAddRelation.relationKey
    	} else if(dcDelSeq != 0) {
    		targetDelRelation = designChange.delPartRelation.where(pr => pr.dcSeq === dcDelSeq).head
    		addParentNo = targetDelRelation.parent.head.name
    	}
    	val designChangeRelationForm = DesignChangeRelationForm(generatePartsListBean(delParentNo, delChildNo, delRelationKey), generatePartsListBean(addParentNo, addChildNo, addRelationKey), designChange.dcNo)
    	Ok(views.html.updateDesignChangeRelationForm(designChangeRelationRegistForm.fill(designChangeRelationForm), designChangeId, addChildNo, ""))
    }
  }
  
  def designChangeRelationModification(partName: String) = Action { implicit request =>
    designChangeRelationRegistForm.bindFromRequest.fold(
        formWithErrors => BadRequest(views.html.updateDesignChangeRelationForm(formWithErrors, 0, "", "")),
        designChangeRelation => {
          inTransaction {
            val designChange = DesignChangeManager().getByName(designChangeRelation.dcno)
            val message = DesignChangeManager().designChangeUpdate(designChangeRelation, partName)
            if(message == null) {
              Redirect(routes.DesignChangeController.designChangeCoverModify(designChange.id, 0, ""))
            } else {
              Ok(views.html.updateDesignChangeRelationForm(designChangeRelationRegistForm.fill(designChangeRelation), designChange.id, partName, message))              }
            }
          }
     )
    
  }

	def generatePartsListBean(parentNo:String, childNo:String, relationKey: String):PartsListBean = {
	  if(childNo.isEmpty()) {
	      PartsListBean(parentNo, childNo, 0, "")
	  } else {
		  PartsListBean(parentNo, childNo, PartManager().getByName(parentNo).partRelation(PartManager().getByName(childNo).id).quantity, relationKey)
	  }
	}

}