package controllers

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

object PartsListController extends Controller{
  
   val Home = Redirect(routes.PartsListController.index(0,0,"",""))
   val Home2 = Redirect(routes.PartsListController.relationRegistration())
   val relationForm = Form(
       mapping(
           "parent" -> nonEmptyText,
           "child" -> nonEmptyText,
           "quantity" -> longNumber,
           "relationKey" -> text
        )(PartsListBean.apply)(PartsListBean.unapply)
    )
    
	def index(opt:Int, page:Int, key:String, relationKey:String) = Action { implicit request =>
	  inTransaction{
	    val partsBuffer = PartsList().getPartsBuffer(opt, page, key, relationKey)
	    var totalCost:Long =0
	    for(partBuffer <- partsBuffer) {
	      totalCost += partBuffer.cost
	    }
	    val row = Integer.decode(Messages("list.row"))
	    Ok(views.html.partslistshow(partsBuffer.drop(page*row).take(row), opt, page, partsBuffer.size, key, totalCost, relationKey))
	  }
	}
   
   def matrixPartList(project: String) = Action { implicit request =>
     var partsListBeans = ArrayBuffer[ArrayBuffer[PartsListShowBean]]()
     var allChildren = ArrayBuffer[Part]()
     var matrixPartsListBeans = HashMap[Part, ArrayBuffer[beans.MultiPartsListBean]]()
     inTransaction {
       if(project != "") {
         val models = ProjectManager().getByName(project).parts
         //  各モデルに対し、部品表抽出処理を実施。
         for(model <- models) {
           // 部品表の１レベル展開。
           val partsListBean = PartsList().getPartsBuffer(0, 0, model.name, "")
           // 全ての部品表配列を蓄積。
           if(partsListBean.size != 0) {
             partsListBeans += partsListBean
           } else {
             // partsListBean が0件の場合、空の部品表配列を蓄積。空リストを表示するため
             partsListBeans += ArrayBuffer(PartsListShowBean(model.name, Part("", null, 0, 0), 0, "", 0))
            }
           }
         // 部品表配列より全ての子部品を蓄積。
         for(partsListBean <- partsListBeans) {
           for(partsList <- partsListBean) {
             //　子品番がブランクは、空リストを表示するためのダミー配列なので、子品番蓄積からは除外。
             if(partsList.child.name!="") {
               allChildren += partsList.child
               }
             }
           }
         matrixPartsListBeans = PartsList().getMatrixPartsList(partsListBeans, allChildren)
         Ok(views.html.matrixpartslistshow(allChildren.distinct, matrixPartsListBeans, allChildren.distinct.size, models, project))
       } else {
         Ok(views.html.matrixpartslistshow(allChildren.distinct, matrixPartsListBeans, allChildren.distinct.size, null, project))
        }
      }
   }

	def upIndex(opt:Int, page:Int, key:String) = Action { implicit request =>
	  var partBuffer = ArrayBuffer[PartsListBean]()
	  inTransaction {
		  for (childPart <- PartManager().getByLikeName(key)) {
		    for(returnPartBuffer <- PartRecursion().up(childPart, opt)) {
		      partBuffer += returnPartBuffer
		    }
		  }
	   }
	   val row = Integer.decode(Messages("list.row"))
	   Ok(views.html.uppartslistshow(partBuffer.drop(page*row).take(row), opt, page, partBuffer.size, key))
	}
	
	def createRelation(parent:String) = Action {implicit request =>
	  Ok(views.html.createRelationForm(relationForm.fill(new PartsListBean(parent, "", 0, "")),""))
	}
	
	def updateRelation(parentNo:String, childNo:String, project:String) = Action { implicit request =>
	  inTransaction {
		  Ok(views.html.updateRelationForm(relationForm.fill(generatePartsListBean(parentNo, childNo)), childNo, project, ""))
	  }
	}
	
	def relationRegistration() = Action { implicit request =>
	  relationForm.bindFromRequest.fold(
	      formWithErrors => BadRequest(views.html.createRelationForm(formWithErrors, "")),
	   data => {
		   inTransaction {
		    val message = PartRelationManager().insert(data, null, 0)
		    if( message == null) {
			  Home.flashing("success" -> "Relation %s has been created".format(data.parent))
		    } else {
	         Ok(views.html.createRelationForm(relationForm.fill(data), message))
		    }
		   }
	  }
     )
	}
	
	def relationUpdate(childName:String, project:String) = Action { implicit request =>
	  relationForm.bindFromRequest.fold(
		   formWithErrors => BadRequest(views.html.updateRelationForm(formWithErrors, null, "", "")),
	   data => {
	     inTransaction {
	       val message = PartRelationManager().update(data, childName)
	       if(message == null) {
	         if(project=="") {
	        	 Home.flashing("success" -> "Relation %s has been created".format(data.parent))
	         } else {
	        	 Redirect(routes.PartsListController.matrixPartList(project))
	          }
	        } else {
	          Ok(views.html.updateRelationForm(relationForm.fill(data), childName, project, message))
	        }
	      }
	    }
	  )
	}
	
	def relationDelete(parentName:String, childName:String) = Action {
	  inTransaction {
	    val data = PartsListBean(parentName, childName, 0, "")
	    PartRelationManager().delete(data, childName)
	    Home.flashing("success" -> "Relation %s has been deleted".format(parentName + "/" + childName))
	  }
	}
	
	def generatePartsListBean(parentNo:String, childNo:String):PartsListBean = {
	  val pr = PartManager().getByName(parentNo).partRelation(PartManager().getByName(childNo).id)
	  if(childNo.isEmpty()) {
	      PartsListBean(parentNo, childNo, 0, pr.relationKey)
	  } else {
		  PartsListBean(parentNo, childNo, pr.quantity, pr.relationKey)
	  }
	}
	
}