package controllers

import mvc.AuthAction
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.immutable.Seq
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 = AuthAction {
     Action { implicit request =>
       if(request == null) {
         Ok(views.html.errors.errorNotAuthentication())
       } else {
         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) = AuthAction {
    Action { implicit request =>
      if(request == null) {
         Ok(views.html.errors.errorNotAuthentication())
      } else {
        inTransaction {
          var partBuffer = Seq[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 = 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) = AuthAction {
    Action { implicit request =>
      if(request == null) {
         Ok(views.html.errors.errorNotAuthentication())        
      } else {
        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) = AuthAction {
    Action { implicit request =>
      if(request == null) {
         Ok(views.html.errors.errorNotAuthentication())        
      } else {
        inTransaction {
          val designChange = DesignChangeManager().getById(designChangeId)
          if(!delParentName.isEmpty()) {
            val delParent = PartManager().getByName(delParentName).head
            val delChild = PartManager().getByName(delChildName).head
            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).head
            val addChild = PartManager().getByName(addChildName).head
            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) = AuthAction {
    Action { implicit request =>
      if(request == null) {
         Ok(views.html.errors.errorNotAuthentication())
      } else {
        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) = AuthAction {
    Action { implicit request =>
      if(request == null) {
         Ok(views.html.errors.errorNotAuthentication())
      } else {
        inTransaction {
          val designChange = DesignChangeManager().getById(designChangeId)
          val ParentPart = PartManager().getByName(targetParentName).head
          val delRelation = designChange.delPartRelation.where(pr => pr.dcSeq === dcSeq).head
          val delPart = delRelation.child.head
          val delPartsListBean = PartsListBean(ParentPart.name, delPart.name, delRelation.quantity, delRelation.relationKey)
          val addRelations = designChange.addPartRelation.where(pr => pr.dcSeq === dcSeq)
          var addPartsListBean = PartsListBean("", "", 0, "")
          // 削除設計変更の場合、addRelationの取得にはいかない
          if(addRelations.size !=0) {
            val addRelation = addRelations.head
            val addPart = addRelation.child.head
            addPartsListBean = PartsListBean(ParentPart.name, addPart.name, addRelation.quantity, addRelation.relationKey)
          } else {
            addPartsListBean = PartsListBean(ParentPart.name, "", 0, "")
           }
          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) = AuthAction {
    Action { implicit request =>
      if(request == null) {
         Ok(views.html.errors.errorNotAuthentication())
      } else {
        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).head.partRelation(PartManager().getByName(childNo).head.id).quantity, relationKey)
	  }
	}

}