package models.services
import forms._
import beans._
import models._
import org.squeryl._
import org.squeryl.PrimitiveTypeMode._
import scala.collection.mutable.ArrayBuffer

case class DesignChangeManager() {
  def designChange(data: DesignChangeRelationForm) = {
    val dc = getByName(data.dcno)
    if(!data.partsListBeanBefore.child.isEmpty()) {
      relationDel(data.partsListBeanBefore.parent, data.partsListBeanBefore.child, data.partsListBeanBefore.quantity, dc, dc.dcSeq)
      }
    if(!data.partsListBeanAfter.child.isEmpty()) {
      relationAdd(data.partsListBeanAfter.parent, data.partsListBeanAfter.child, data.partsListBeanAfter.quantity, dc, dc.dcSeq)
    }
    dc.dcSeq += 1
    PartsListDb.designChanges.update(dc)
  }
  
  def designChangeList(request: play.api.mvc.Request[play.api.mvc.AnyContent]): String = {
      var designChangeList:String = ""
        inTransaction {
          val designChanges = PartsListDb.designChanges.where(dc => dc.dcNo like request.getQueryString("q").get + "%")
          for(designChange <- designChanges) {
            designChangeList = designChangeList.concat(designChange.dcNo)
            designChangeList = designChangeList.concat("\n")
            }
         }
      return designChangeList
  }
  
  def insert(designChange: DesignChangeForm) = {
    PartsListDb.designChanges.insert(DesignChange(designChange.dcNo, designChange.dcDescription, 1))
  }
  
  def update(id: Long, designChange: DesignChangeForm) = {
    val updDesignChange = getById(id)
    updDesignChange.dcNo = designChange.dcNo
    updDesignChange.dcDescription = designChange.dcDescription
    PartsListDb.designChanges.update(updDesignChange)
  }
  
  def getDesinChangeInformation(designChange: DesignChange): ArrayBuffer[DesignChangeListBean] = {
      var designChangeBuffer = ArrayBuffer[DesignChangeListBean]()
      //変更情報および削除情報をバッファ
      for(delPart <- designChange.delPartRelation) {
        var checkch = 0
        for(addPart <- designChange.addPartRelation) {
          if(delPart.dcSeq == addPart.dcSeq) {
        	  designChangeBuffer += DesignChangeListBean(delPart.dcSeq, delPart.parent.head.name, delPart.child.head.name, delPart.quantity, delPart.dcSeq, addPart.parent.head.name, addPart.child.head.name, addPart.quantity, addPart.dcSeq)
        	  checkch = 1
           }
         }
        if(checkch == 0) {
         designChangeBuffer += DesignChangeListBean(delPart.dcSeq, delPart.parent.head.name, delPart.child.head.name, delPart.quantity, delPart.dcSeq, "", "", 0, 0) 
         }
        }
      //追加情報をバッファ        
      for(addPart <- designChange.addPartRelation) {
         var checka = 0
         for(designChange <- designChangeBuffer) {
      	   if(designChange.dcSeq == addPart.dcSeq) {
      	     checka = 1
       	    }
           }
         if(checka == 0) {
             designChangeBuffer += DesignChangeListBean(addPart.dcSeq, "", "", 0, 0, addPart.parent.head.name, addPart.child.head.name, addPart.quantity, addPart.dcSeq)
          }
      }
      return designChangeBuffer
  }
  
  def designChangeCancel(id: Long) = {
    val cancelDesignChange = getById(id)
    for (cancelAddRelation <- cancelDesignChange.addPartRelation) {
      relationAddCancel(cancelAddRelation.parent.head, cancelAddRelation.child.head)
    }
    for (cancelDelRelation <- cancelDesignChange.delPartRelation) {
      relationDelCancel(cancelDelRelation)
    }
  }
  
  def designChangeAddCancelBySeq(designChangeId: Long, dcSeq: Long) = {
    val designChange = getById(designChangeId)
    val cancelAddRelation = designChange.addPartRelation.where(pr => pr.dcSeq === dcSeq).head
    relationAddCancel(cancelAddRelation.parent.head, cancelAddRelation.child.head)
  }

  def designChangeDelCancelBySeq(designChangeId: Long, dcSeq: Long) = {
    val designChange = getById(designChangeId)
    val cancelDelRelation = designChange.delPartRelation.where(pr => pr.dcSeq === dcSeq).head
    relationDelCancel(cancelDelRelation)
  }

  def designChangeUpdate(data: DesignChangeRelationForm, partName: String) = {
    val dc = getByName(data.dcno)
    // 更新時に、子品番の変更が無ければ、単純な員数更新
    if(data.partsListBeanAfter.child == partName) {
      val updateRelation = dc.addPartRelation.where(pr => pr.parentId === PartManager().getByName(data.partsListBeanAfter.parent).id and
          pr.childId === PartManager().getByName(data.partsListBeanAfter.child).id).head
      updateRelation.quantity = data.partsListBeanAfter.quantity
      PartsListDb.partRelations.update(updateRelation)      
    } else {
    // 更新時に、子品番の変更は、設計変更追加をキャンセル
      val parent = PartManager().getByName(data.partsListBeanAfter.parent)
      var dcSeq: Long = 0L
       // 更新前品番がブランクで無ければ、設計変更の追加をキャンセル
      if(!partName.isEmpty()) {
        val cancelChild = PartManager().getByName(partName)
    	 val updateRelation = dc.addPartRelation.where(pr => pr.parentId === parent.id and
    	  		pr.childId === cancelChild.id).head
    	 dcSeq = updateRelation.dcSeq
    	 relationAddCancel(updateRelation.parent.head, updateRelation.child.head)
      } 
      // 更新後品番がブランクでなければ、設計変更の追加処理
      if(!data.partsListBeanAfter.child.isEmpty()) {
        val child = PartManager().getByName(data.partsListBeanAfter.child)
    	 val updateRelation = dc.delPartRelation.where(pr => pr.parentId === parent.id and
    	  		pr.childId === PartManager().getByName(data.partsListBeanBefore.child).id).head
        dcSeq = updateRelation.dcSeq
      relationAdd(parent.name, child.name, data.partsListBeanAfter.quantity, dc, dcSeq)
      }
    }
  }
  
  def relationDel(parentNo: String, childNo: String, quantity: Long, dc: DesignChange, dcSeq: Long) = {
      val parent = PartManager().getByName(parentNo)
      val delRelation = parent.parts.assign(PartManager().getByName(childNo))
      dc.delPartRelation.assign(delRelation)
      relationUpdate(delRelation, quantity, dcSeq)
  }
  
  def relationAdd(parentNo: String, childNo:String, quantity: Long, dc: DesignChange, dcSeq: Long) = {
      val parent = PartManager().getByName(parentNo)
      val addRelation = parent.parts.associate(PartManager().getByName(childNo))
      dc.addPartRelation.associate(addRelation)
      relationUpdate(addRelation, quantity, dcSeq)
  }
  
  def relationAddCancel(parent: Part, child: Part) = {
      parent.parts.dissociate(child)    
  }
  
  def relationDelCancel(cancelDelRelation: PartRelation) = {
      cancelDelRelation.delDcId = 0L
      cancelDelRelation.dcSeq = 0L
      PartsListDb.partRelations.update(cancelDelRelation) 
    
  }

  def relationUpdate(updateRelation: PartRelation, quantity: Long, dcSeq: Long) = {
      updateRelation.quantity = quantity
      updateRelation.dcSeq = dcSeq
      PartsListDb.partRelations.update(updateRelation)
  }
  
  def getById(id: Long): DesignChange = {
    PartsListDb.designChanges.where(dc => dc.id === id).head
  }
  
  def getByName(dcNo: String): DesignChange = {
    PartsListDb.designChanges.where(dc => dc.dcNo === dcNo).head
  }
  
  def list(key: String): org.squeryl.Query[DesignChange] = {
      PartsListDb.designChanges.where(dc => dc.dcNo like key + "%")
  }
  
  def getTargetRelationByDesignChangeId(id: Long): Iterable[PartRelation] = {
    PartsListDb.designChanges.where(dc => dc.id === id ).head.delPartRelation.++:(PartsListDb.designChanges.where(dc2 => dc2.id === id).head.addPartRelation)
  }

}