/**
 * This class writes English and Picture files
 * for the approximate compilation, derived in
 * Tuc07a- arXiv:0706.0479,
 * for the evolution operator 
 * e^{iH_{fruit}}, where H_{fruit} is dictated
 * by the algorithm of FGG (Farhi, Goldstone, Gutmann)
 * that appears in ArXiv:quant-ph/0702144.
 */

public class FruitSEO_writer  extends SEO_writer{
	
	//private String 	_filePrefix;
	private int  	_lineNumBits;
	private int  	_treeNumBits;
	private int  	_lvsNumBits;
	//private int 		_numBits;
	
    private double 	_strength;

	private int  _lineDoor;
	private Pair  _pair;

 	private OracleBands _bands;

	private int  _lineNumTrots;
	private int  _lineSuzukiHalfOrder;
	
	private int  _treeNumTrots;

	
	private int  _metaNumTrots;
	private int  _metaSuzukiHalfOrder;



/**
 * 
 */	
	public FruitSEO_writer(
	        String 	filePrefix,
	        int lineNumBits,
	        int treeNumBits,
	        double strength,
	        int lineDoor,
			OracleBands bands,
			int  lineNumTrots,
			int  lineSuzukiHalfOrder,			
			int  treeNumTrots,
			int  metaNumTrots,
			int  metaSuzukiHalfOrder)
	{ 	
	 	
    	super(filePrefix + "_qfru", 2 /*_numBits, temporary*/);
    	
    	
		Throw.If(lineNumBits<2 , 
			"lineNumBits of bits must be >= 2");  
		Throw.If(treeNumBits<2 , 
			"treeNumBits of bits must be >= 2");  
		_lineNumBits = lineNumBits;    	
		_treeNumBits = treeNumBits;
		_lvsNumBits = treeNumBits-1;//lvs = leaves
		
	 	int lineNumRows = 1<<lineNumBits;
	   	int treeNumRows = 1<<treeNumBits;
	   	int lvsNumRows = 1<<_lvsNumBits;
	    int numRows = lineNumRows + treeNumRows + lvsNumRows;
	    int numBits = 0;
	    while((1<<numBits) < numRows){numBits++;}
	    _numBits = numBits;
	
    	_strength = strength;
	            
		_lineDoor = lineDoor;
		//pair = pair of states that is glued.
		//lineNumRows is dud state
		_pair = new Pair(lineNumRows+1, lineDoor);
		
		_bands = new OracleBands(bands);
		
		_lineNumTrots = lineNumTrots;
		_lineSuzukiHalfOrder = lineSuzukiHalfOrder;			
		_treeNumTrots = treeNumTrots;
		_metaNumTrots = metaNumTrots;
		_metaSuzukiHalfOrder = metaSuzukiHalfOrder;


		write();
		
        closeFiles();

	}
/**
 * 
 */
	public void write(){
		
        SuzWriter sw = new SuzWriter();
        SuzFunctions funs = new SuzFuns1();
    	if(_metaNumTrots>1){
    		int loopNum = getLineCount();
    		writeLOOP(loopNum, _metaNumTrots);
    		SuzWriter.writeSuzuki2k(_metaSuzukiHalfOrder, 
    				_strength/_metaNumTrots, true, funs);
    		writeNEXT(loopNum);
    	}else{
    		SuzWriter.writeSuzuki2k(_metaSuzukiHalfOrder, 
    				_strength, true, funs);
    	}
	}
		
/**
*
*/
    private class SuzFuns1 extends SuzFunctions{
    /**
     * 
     */
	    public void writeExpBtimes(double t){
   	
	    	new GlueSEO_writer(
	    	        _englishOut, 
	    	        _pictureOut,
	    	        true, // doWrite
	    	        _numBits, 
	    	        0,//bit padding
	    	        t,//strength
	    			_pair);

	    	
	    	int shift = (1<<_lineNumBits) + (1<<(_treeNumBits-1));
	    	new ShiftSEO_writer(
	    	        _englishOut, 
	    	        _pictureOut,
	    	        true, // doWrite
	    	        _numBits, 
	    	        0,//bit padding
	    	        shift);
	    	
	    	new OracleSEO_writer(
	    	        _englishOut, 
	    	        _pictureOut,
	    	        true, // doWrite
	    	        _treeNumBits, 
	    	        _numBits - _treeNumBits,//bit padding 
	    	        t,//strength
	    			_bands);
	    	
	    	new ShiftSEO_writer(
	    	        _englishOut, 
	    	        _pictureOut,
	    	        true, // doWrite
	    	        _numBits, 
	    	        0,//bit padding
	    	        -shift);
	    	

		
	  	}

/**
*
*/
	    public void writeExpAtimes(double t){
	   	
	    	new LineSEO_writer(
	    	        _englishOut, 
	    	        _pictureOut,
	    	        true, // doWrite
	    	        _lineNumBits, 
	    	        _numBits - _lineNumBits,//bit padding 
	    	        t,//strength
	    	        _lineNumTrots,
	    	        _lineSuzukiHalfOrder);
	   	
	    	int shift = 1<<_lineNumBits;
	    	new ShiftSEO_writer(
	    	        _englishOut, 
	    	        _pictureOut,
	    	        true, // doWrite
	    	        _numBits, 
	    	        0,//bit padding
	    	        shift);

	    	new TreeSEO_writer(
	    	        _englishOut, 
	    	        _pictureOut,
	    	        true, // doWrite
	    	        _treeNumBits, 
	    	        _numBits - _treeNumBits,//bit padding 
	    	        t,//strength
	    	        _treeNumTrots);
	    	
	    	new ShiftSEO_writer(
	    	        _englishOut, 
	    	        _pictureOut,
	    	        true, // doWrite
	    	        _numBits, 
	    	        0,//bit padding
	    	        -shift);
	   
			
	    }		
	}
	

}
