/*
 * Created on Jul 19, 2005
 */
package com.isoft.mmcd.library;



import java.io.Serializable;
import java.util.ArrayList;





import com.isoft.mmcd.content2.CTLibraryParser;


import com.isoft.mmcd.content2.LibraryManager;
import com.isoft.mmcd.utils.ThrowableHandler;
import com.isoft.mmcd.utils.cfgreader.MCCompoundProperty;


public class CBookStructure implements Serializable
{
	private int id;
	//private String nick;
	private String structureFile;
	//private String title ;
	
	private String  dataFile;
	
	private String mp3FileName;
	
	//private String[] basicInfo;	
	//private String[] mp3Names;
	
	private CParagraph[] paragraphs;
	
	private int curentPage;
	private int totalPageCount;
	private boolean hasSpeech = false;
	private boolean structureCreated = false;
	
	private ArrayList pictureInfos ;
	private boolean hasPicture = false;
	
	
	public CBookStructure( MCCompoundProperty bookProps ,int bId)
	{
		
		try
		{		
			this.structureFile = bookProps.getAtomicProperty("$structure").getValue();
			this.dataFile = bookProps.getAtomicProperty("$data").getValue();
			this.mp3FileName  = bookProps.getAtomicProperty("$mp3").getValue();	
			//this.nick	  = bookProps.getAtomicProperty("$nick").getValue();
			//this.title	  = bookProps.getAtomicProperty("$title").getValue();
			
			this.hasSpeech	  = bookProps.getAtomicProperty("$hasspeech").getBooleanValue();
			this.id = bId;
			
			this.createAllStructure();
			
		}catch(Throwable t)
		{
			ThrowableHandler.getInstance().addThrowable(t , ThrowableHandler.S_FATAL);
			System.err.println("while creating book"+bId);
		}

         
	}
	
	
	
	public int getRealPageofOsmanicTree( int turkishPage)
	{
		for( int i=0 ; i < this.getParagraphs().length ; i++ )
		{
			//TODO how to decide to the page of osmanic
			CParagraph cpar =  this.getParagraphJ( i );			
			if( cpar.getOsmanicPage() == turkishPage && cpar.getType() == Library_Constants.CT_NEWP )
				return cpar.getPage();
		}
		return -1;
	}
	
	public int getFirstIndependentFileOfPage(int pid)
	{
		int len = this.paragraphs.length;
		int lastVal = 0;
		for(int i=0;i < len;i++)
		{
	
			CParagraph ctf =    this.paragraphs[i];
			int tempType = ctf.getType();
			boolean independentType = false ;
			if( tempType == Library_Constants.CT_NEWP  || tempType == Library_Constants.CT_TINDENT || 
					tempType == Library_Constants.CT_MAYBEHEAD  || tempType == Library_Constants.CT_TABBED 
					 || tempType == Library_Constants.CT_3STAR)
				independentType = true;
						
			
		
			if(pid ==  ctf.getPage() && independentType )
				return i;
		}
		return -1;
		
	}
	
	public int getNextPrintablePage(int pid)
	{
		//get ifr
		int len = this.paragraphs.length;
		int lastVal = 0;
		for(int i=0;i < len;i++)
		{
	
			CParagraph ctf =    this.paragraphs[i];
			int tempType = ctf.getType();
			boolean independentType = false ;
			if( tempType == Library_Constants.CT_NEWP  || tempType == Library_Constants.CT_TINDENT || 
					tempType == Library_Constants.CT_MAYBEHEAD  || tempType == Library_Constants.CT_TABBED 
					 || tempType == Library_Constants.CT_3STAR)
				independentType = true;
						
			
		
			if( ctf.getPage() >= pid    && independentType )
				return ctf.getPage() ;
		}
		return -1;
		
	}
	
	public int getPreviousPrintablePage(int pid)
	{
		
		if( pid < this.getFirstPageNumber() )
			return this.getFirstPageNumber();
		
		if( pid > this.getLastPageNumber() )
			return this.getLastPageNumber();
			
		//get ifr
		int len = this.paragraphs.length;
		int lastVal = 0;
		for(int i=len -1  ; i > -1 ; i--)
		{
	
			CParagraph ctf =    this.paragraphs[i];
			int tempType = ctf.getType();
			boolean independentType = false ;
			if( tempType == Library_Constants.CT_NEWP  || tempType == Library_Constants.CT_TINDENT || 
					tempType == Library_Constants.CT_MAYBEHEAD  || tempType == Library_Constants.CT_TABBED 
					 || tempType == Library_Constants.CT_3STAR)
				independentType = true;
						
			
		
			if( ctf.getPage() <= pid    && independentType )
				return ctf.getPage() ;
		}
		return -1;
		
	}
	
	public int getFirstFileOfPage(int pid)
	{
		int len = this.paragraphs.length;
		int lastVal = 0;
		for(int i=0;i < len;i++)
		{
				
			CParagraph ctf =    this.paragraphs[i];
			if( pid ==  ctf.getPage() )
				return i;
		}
		return 0;
		
	}
	
	public int  getFirstPageNumber()
	{
		return this.getParagraphJ( 0 ).getPage();
	}
	
	public int  getLastPageNumber()
	{
		return this.getParagraphJ( this.getParagraphs().length - 1 ).getPage();
	}
	
	public String[] loadMp3Relations()
	{
		if( !this.hasSpeech )
			return null ;
		
		String allNames = 	LibraryManager.getLibraryFile(this.mp3FileName,LibraryManager.TYPE_MP3FILE ,"utf-8");
        
		/*if(allNames != null && allNames != "" )
			this.mp3Names = allNames.split("Dosya");*/
		return allNames.split("Dosya");
		//allNames = null;
	}
	
	private void loadPictures()
	{
		String pictureText = LibraryManager.getLibraryFile(this.getStructureFile() , LibraryManager.TYPE_PICTURE ,"iso-8859-9");
		if( pictureText == null || pictureText == "" )
			return ;
		
		this.pictureInfos = new ArrayList();
		this.hasPicture = true;
		String[] pictures = pictureText.split("\n");
		for(int i = 0; i < pictures.length ; i++)
		{
			CPictureInfo cpicinfo = new CPictureInfo( pictures[ i ] );
			cpicinfo.setPositionOnArray(  this.findPositionOnArray( cpicinfo.getInfo()) );
			this.pictureInfos.add( cpicinfo );
		}
		
	}
	public void createAllStructure()
	{
		
		//this.loadBasicInfo();
		
		//this.pageBasedInfo = new String[ this.basicInfo.length ];
		
		//this.loadMp3Relations();
		this.createCTFiles();
		this.loadPictures();
		
	}
	/*
	public boolean hasArabicParagraph(ArrayList parIndexes)
	{
		for(int i=0 ; i < parIndexes.size() ; i++)
		{
			String s = 	this.arabicInfo[ ((Integer) parIndexes.get( i) ).intValue() ];
			int sepIndex = s.indexOf(")");
			String type = s.substring( sepIndex + 1);
			int typeVal = Integer.parseInt( type );
			if( typeVal == StringUtils.ARABIC_AND_TURKISH || typeVal == StringUtils.ALL_ARABIC  )
				return true;
			
		}
		return false;
	}*/
	
	public String[] loadBasicInfo()
	{
		String basicText = LibraryManager.getLibraryFile(this.getStructureFile() , LibraryManager.TYPE_STRUCTURE ,"iso-8859-9");
		
		return basicText.split("\n");
		
		
		//basicText = LibraryManager.getLibraryFile(this.getStructureFile() , LibraryManager.TYPE_ISARABIC ,"iso-8859-9");
		
		//this.arabicInfo = basicText.split("\n");
		//basicText = null;
		
		//if( arabicInfo.length != basicInfo.length )
		//	System.out.println("the sizes of infos do not match");
	}
	
	public void findPositionsOnArray(CTopic ctp)
	{
		ctp.setBegin( this.findPosition( ctp.getFirstPage() , ctp.getFirstId() ) );
		
		ctp.setEnd( this.findPosition( ctp.getLastPage() , ctp.getLastId() ) );

	}
	
	public int findPosition(int pageid , int enumeration )
	{
		for(int i=0 ; i < this.paragraphs.length  ;i++)
		{
			CParagraph cpar =	this.paragraphs[ i ];
			if( cpar.getPage() == pageid && cpar.getEnum_Inpage() == enumeration )			
				return i;
		}

		return -1;
	}
	
	public int findPositionOnArray(String nodeText)
	{
		int pno =	CTLibraryParser.getTreePageNumber( nodeText );
		int enumNo = CTLibraryParser.getTreeEnumerationNumber( nodeText );

		return this.findPosition( pno , enumNo ) ;
		
	}	

	
	private void createCTFiles()
	{
		String[] basicInfoStructure = this.loadBasicInfo();
		String[] mp3Data = this.loadMp3Relations();
		
		this.paragraphs = new CParagraph[basicInfoStructure.length ];
		int curentCrossPage = -1;
		for(int i=0;i < basicInfoStructure.length  ;i++)
		{
			int ctType =  CTLibraryParser.getParagraphType( basicInfoStructure[ i ]  ); 
			
			if( ctType > 30000 && ctType < 40000 )
			{
				// I MARKED PAGE BEGINNINGS SO THAT I DO NOT NEED ACCESS
				// FILES FOR PAGE NUMBERS
				this.curentPage = ctType - 30000;
				this.totalPageCount++;
					
				ctType = Library_Constants.CT_SH ;
			}
			
			if(  ctType > 40000 )
			{
				curentCrossPage = ctType - 40000;
			}
			
			this.paragraphs[ i ] = new CParagraph( i , ctType , this.curentPage  , this.getMp3Name( basicInfoStructure[ i ] ,mp3Data ),basicInfoStructure[ i ] , curentCrossPage);
			 
			
		}
		
        
	}
	
	public int getFirstParagraphOfPage(int pno)
	{
		for(int i=0;i < this.paragraphs.length ;i++ )
		{
			if( this.paragraphs[ i ].getPage() == pno)
			{
				return i;
				
			}
		}
		return -1;
	}
	
	public int getLastJoinedParagraphOfPage(int pno  )
	{
		int pageLastParagraf = this.getLastParagraphOfPage( pno );
		
		if( pno == this.getLastPageNumber() )
			return this.paragraphs.length - 1;
			
		for(int i=pageLastParagraf+1 ;i < this.paragraphs.length ;i++ )
		{
			int type = this.paragraphs[ i ].getType();
			if( type == Library_Constants.CT_TABBED ||  type == Library_Constants.CT_NEWP
				       || type == Library_Constants.CT_TINDENT ||  type == Library_Constants.CT_MAYBEHEAD
					   || type == Library_Constants.CT_3STAR )
			{
				return i ;
				
			}
		}
		return -1;
	}
	
	public int getLastParagraphOfPage(int pno)
	{
		if( pno == this.getLastPageNumber() )
			return this.paragraphs.length - 1;
			
		for(int i=0;i < this.paragraphs.length ;i++ )
		{
			if( this.paragraphs[ i ].getPage() > pno)
			{
				return i - 1;
				
			}
		}
		return -1;
	}
	
	public CParagraph getParagraphJ(int j)
	{
		return this.paragraphs[ j ];
	}
	
	public String parseMp3Name(String s)
	{
          
        //still support multiple mp3 
        //with comma remove below parse mp3 legally
        
		//	Dosya:1?info=s3_p1>-Mp3s)B3.mp3,
		//	Dosya:1?info=s3_p1>-Mp3s)B3.mp3ANDB3-1.Mp3,
		
		int index = s.indexOf(")");
		s = s.substring(index+1);
		/*if( s.indexOf( "AND") > -1 )
		{
			String[] multipleMp3s = s.split("AND");
			return multipleMp3s;
		}*/
		
		return  s ;
	}
	
	
	/*public String getMp3Names(String info , String[] mp3Data)
	{
		//Dosya:1?info=s3_p1>-Mp3s)B3.mp3ANDB3-1.mp3,
		//9 =s5_p3x  ) 2
		
		if( ! this.hasSpeech )
			return "nospeech";
			
		if( mp3Data == null )
			return "no-mp3";
		
		int index1 = info.indexOf("=");
		int index2 = info.indexOf("x");
		String identifier = info.substring( index1 + 1 ,index2 );
		
		for( int i = 0; i < mp3Data.length ; i++)
		{
			if( mp3Data[i].indexOf( identifier ) > -1  )
			{
				return this.parseMp3Name( mp3Data[ i ] );
			}
		}
		
		return "not-found-mp3";
	}*/
	
	public String getMp3Name(String info ,String[] mp3Data)
	{
		//Dosya:1?info=s3_p1>-Mp3s)B3.mp3,
		//9 =s5_p3x  ) 2
		
		if( ! this.hasSpeech )
			return null;
			
		if( mp3Data == null )
			return null;
		int index1 = info.indexOf("=");
		int index2 = info.indexOf("x");
		String identifier = info.substring( index1 + 1 ,index2 );
		
		for( int i = 0; i < mp3Data.length ; i++)
		{
			if( mp3Data[i].indexOf( identifier ) > -1  )
			{
				return this.parseMp3Name( mp3Data[ i ] );
			}
		}
		
		return null ;
	}
	
	
	//GETTERS AND SETTERS
	
	public String getDataFile() {
		return dataFile;
	}
	public void setDataFile(String dataFile) {
		this.dataFile = dataFile;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
	public String getStructureFile() {
		return structureFile;
	}
	public void setStructureFile(String structureFile) {
		this.structureFile = structureFile;
	}
	public CParagraph[] getParagraphs() {
		return paragraphs;
	}
	public void setParagraphs(CParagraph[] paragraphs) {
		this.paragraphs = paragraphs;
	}
	public boolean isHasSpeech() {
		return hasSpeech;
	}
	public void setHasSpeech(boolean hasSpeech) {
		this.hasSpeech = hasSpeech;
	}
	
	public boolean isHasPicture() {
		return hasPicture;
	}
	public void setHasPicture(boolean hasPicture) {
		this.hasPicture = hasPicture;
	}
	public ArrayList getPictureInfos() {
		return pictureInfos;
	}
	public void setPictureInfos(ArrayList pictureInfos) {
		this.pictureInfos = pictureInfos;
	}
    public String getMp3FileName( )
    {
        return this.mp3FileName ;
    }
    public void setMp3FileName( String mp3FileName )
    {
        this.mp3FileName = mp3FileName ;
    }
    
}
