package net.java.amateras.xlsbeans.processor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;

import jxl.Cell;
import jxl.Sheet;
import net.java.amateras.xlsbeans.NeedPostProcess;
import net.java.amateras.xlsbeans.Utils;
import net.java.amateras.xlsbeans.XLSBeansException;
import net.java.amateras.xlsbeans.annotation.LabelledCell;
import net.java.amateras.xlsbeans.xml.AnnotationReader;

/**
 * The {@link net.java.amateras.xlsbeans.processor.FieldProcessor} 
 * inplementation for {@link net.java.amateras.xlsbeans.annotation.LabelledCell}.
 * 
 * @author Naoki Takezoe
 * @see net.java.amateras.xlsbeans.annotation.LabelledCell
 */
public class LabelledCellProcessor implements FieldProcessor {

	public void doProcess(Sheet sheet, Object obj, 
			Method setter, Annotation ann, AnnotationReader reader,
			List<NeedPostProcess> needPostProcess) throws Exception {
		
		LabelledCell cell = (LabelledCell)ann;
		Cell targetCell = null;
		
		int column = -1;
		int row = -1;
		
		if(cell.label().equals("")){
			column = cell.labelColumn();
			row = cell.labelRow();
		} else {
			try {
				if(cell.headerLabel().equals("")){
					Cell labelCell = Utils.getCell(sheet, cell.label(), 0);
					column = labelCell.getColumn();
					row = labelCell.getRow();
				} else {
					Cell headerCell = Utils.getCell(sheet, cell.headerLabel(), 0);
					Cell labelCell = Utils.getCell(sheet, cell.label(), headerCell.getRow() + 1);
					column = labelCell.getColumn();
					row = labelCell.getRow();
				}
			} catch(XLSBeansException ex){
				if(cell.optional()){
					return;
				} else {
					throw ex;
				}
			}
		}
		
		int range = cell.range();
		if(range < 1){
			range = 1;
		}
		
		for(int i=0; i<range; i++){
			switch(cell.type()){
			case Left:
				targetCell = sheet.getCell(column - (1 * (i + 1)), row);
				break;
			case Right:
				targetCell = sheet.getCell(column + (1 * (i + 1)), row);
				break;
			case Bottom:
				targetCell = sheet.getCell(column, row + (1 * (i + 1)));
				break;
			default:
				throw new XLSBeansException("Cell type is invalid.");
			}
			if(targetCell.getContents().length()>0){
				break;
			}
		}
		if(targetCell.getContents().length() > 0){
			Utils.setPosition(targetCell.getColumn(), targetCell.getRow(), obj, setter);
		} else {
			Utils.setPosition(column, row, obj, setter);
		}
		Utils.invokeSetter(setter, obj, targetCell.getContents());
	}
	
}
