/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package gf;

import org.opengion.fukurou.business.BizLogic_TABLE;
import org.opengion.penguin.math.ga.HybsGeneticAlgorithm;
import org.opengion.penguin.math.ga.AbstractHybsGAChromosome;
import org.opengion.penguin.math.ga.HybsGAObjectImpl;
import org.opengion.penguin.math.ga.HybsGAObject;
import org.opengion.penguin.math.ga.HybsScheduleChromosome;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

/**
 * penguinパッケージの遺伝的アルゴリズムを利用するためのサンプルです。
 * 
 * GF45を利用してスケジュールを構築します。
 * 名称 PN
 * 工数 KOSU
 * 納期 NOKI(最初からの積み上げ工数)
 * として受け取り、PNの最初の文字とその次の文字（のint値)が作業割り当て対象とします
 * 
 * @version 5.0
 * @author Takahashi Masakazu
 * @since JDK1.7,
 */
public class GFX026A extends BizLogic_TABLE {

	private HybsGAObject gaobjects[];
	
	/**
	 * メインカーソルの各行(変更区分の各処理の前)で呼ばれるチェックロジックを定義します。
	 * 
	 * @param row 行番号
	 * @return 処理が正常終了したか
	 */
	protected boolean befchk( final int row ) {
		return true;
	}

	/**
	 * メインカーソルの各行(変更区分の各処理の前)で呼ばれるチェックロジックを定義します。
	 * 
	 * @param row 行番号
	 * @return 処理が正常終了したか
	 */
	protected boolean first(){
		gaobjects = new HybsGAObject[table.getRowCount()]; // 行数分用意
		return true;
	}
	
	/**
	 * メインカーソルの各行で呼ばれるロジックを定義します。
	 * 
	 * @param row 行番号
	 * @return 処理が正常終了したか
	 */
	protected boolean befall( final int row ) {
		String pn = line("PN");
		String targets[] = new String[] { pn.substring(0,1), pn.substring(1,2)};
		
		gaobjects[row] = new HybsGAObjectImpl( line("PN"), lined("KOSU"), null, new double[] {lined("NOKI")} , targets );
		return true;

		// パラメーターを与えて、サブルーチンを呼び出します。
//		return call( "gf.GF0001", "SYSTEM_ID,CLM,LANG,KBSAKU,NAME_JA,LABEL_NAME", "[SYSTEM_ID],[CLM],[LANG],[KBSAKU],[NAME_JA],[LABEL_NAME]" );
	}

	/**
	 * 最後の行の終わりで呼び出し
	 * 
	 * @param row 行番号
	 * @return 処理が正常終了したか
	 */
	protected boolean last(){
		AbstractHybsGAChromosome rtn2 = new HybsGeneticAlgorithm()
			.setChromosomeClazz("org.opengion.penguin.math.ga.HybsScheduleChromosome")
			.setPopulationSize(300)
			.setGAList( gaobjects )
			.execute();
		
		rtn( tasks(rtn2) );
		
		return true;
	}
	
	/**
	 * 結果を画面に表示するための処理
	 * 
	 */
	private String tasks(AbstractHybsGAChromosome ahgac){
		String rtn = "";
		List<HybsGAObject> representation = ahgac.getThisRepresentation();
		double nokisum = 0.0;
		HashMap<String,Double> machineList = new HashMap<String, Double>(); //名前は機械リストだが、人でも良い
		HashMap<String, ArrayList<String>> taskSchedule = new HashMap<String, ArrayList<String>>();
		
		// HybsScheduleChromosomeクラスの積み上げ処理をそのまま利用します
		nokisum = ((HybsScheduleChromosome)ahgac).makeSchedule( representation, machineList, taskSchedule );
		
		
		for( String m : taskSchedule.keySet() ){
			rtn += m +" : " ;
			for( String s : taskSchedule.get(m) ){
				rtn += s + " | ";
			}
			
			rtn += "("+machineList.get(m)+")";
			rtn += "<br/>";
		}
		
		return rtn;
	}
}
