/**
 * @(#)SWFDocument.java
 * @author  Intelligent Technology Inc.
 * @version 1.00 2002/4
 */
package	jp.co.iti.swf;

import	java.io.*;
import	java.util.*;

import	jp.co.nri.rid.analyzer.FileNameStudio;

/**
 * SWFファイル自体を表す。
 */
public class SWFDocument{
	private	SWFHeader	Header;
	private	SWFTags		Tags;
	
	/**
	 * @since	1.00
	 */
	public	SWFDocument(){
		Header = new SWFHeader();
	}
	
	/**
	 * すでにあるSWFファイルを開くコンストラクタ
	 * @param	name	開くSWFファイルのパス
	 * @since	1.00
	 */
	public	SWFDocument(String name)
		throws	 FileNotFoundException ,SecurityException ,IOException
				,SWFHeaderException ,SWFBodyException ,SWFActionTagException
				,SWFExportAssetsTagException ,SWFImportAssetsTagException
				,SWFActionRecordException ,SWFButtonTagException ,SWFButtonTagException
				,SWFButton2TagException ,SWFActionRecordsException ,SWFButtonRecordsException
				,jp.co.nri.rid.error.RidException
	{
		SWFInputStream swfstream = new SWFInputStream(name);
		try{
			Header	= swfstream.readHeader();
			if(Header.isCompressed){
/*
				
				int blen = 4096;
				byte[] buf = new byte[blen];
				
				Inflater inflater = new Inflater(false);
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				while(true){
					int rlen = swfstream.read(buf);
					if(0 > rlen)	break;
					
					baos.write(buf, 0, rlen);
				}
				

				inflater.setInput(baos.toByteArray());
				
//				ByteArrayOutputStream baos = new ByteArrayOutputStream();
//				while(true){
//					int rlen = inflater.inflate(buf);
					
//					if(0 > rlen)	break;
					
//					baos.write(buf, 0, rlen);
//				}
				
*/
/*
				FileInputStream fis = new FileInputStream(name);
				fis.skip(8);
				swfstream = new SWFInputStream(new InflaterInputStream(fis));
*/
			}
			
/*
			int i=0;
			while( true ){
				int c = swfstream.read();
				if(0 > c) break;
			}
*/
			Tags	= swfstream.readTags();
		}finally{ swfstream.close(); }
		
/*
		for (Enumeration enum = Tags.elements();enum.hasMoreElements();){
			SWFTag tag = (SWFTag)enum.nextElement();
		}
*/
	}
	
	/**
	 * ヘッダ情報を取得する。
	 * @return	このSWFファイルのヘッダ情報のクローン。
	 * 			このメソッドで得たヘッダ情報を編集してもSWFDocumentおよびSWFファイルには反映されない。
	 * @since	1.00
	 */
	public	SWFHeader	getHeader(){	return (SWFHeader)Header.clone();	}
	
	/**
	 * URL情報を取得する。
	 * @return	このSWFが参照しているURLのリスト。
	 * @since	1.00
	 */
	public	String[]	getURLs() throws jp.co.nri.rid.error.RidException {
		Vector urls = new Vector();
		getURLs(Tags.getTags() ,urls);
		return (String[])urls.toArray(new String[0]);
	}
	
	private	void getURLs(SWFTag[] tags ,Vector urls) throws jp.co.nri.rid.error.RidException {
		if(null==tags)	return;
		
		int mx = tags.length;
		for(int i=0;i<mx;i++){
			SWFTag tag = tags[i];
			if(tag instanceof hasSWFActionRecord){
				SWFActionRecord[] actions = ((hasSWFActionRecord)tag).getActionRecords();
				
				if(null==actions)	continue;
				
				int mx2 = actions.length;
				for(int j=0;j<mx2;j++){
					SWFActionRecord action = actions[j];
					if(action instanceof SWFGetURLAction){
						String url = ((SWFGetURLAction)action).getURL();
						if(!url.toLowerCase().startsWith("fscommand:")) urls.add(url);
					}
					else if(action instanceof SWFPushAction){
						SWFPushAction push = (SWFPushAction)action;
						if(SWFPushAction.STRING == push.getType()){
							Object[] lits = push.getLiteral();
							for(int k = lits.length - 1; 0 <= k; k--){
								String url = (String)lits[k];
								if(FileNameStudio.checkForSWF(url))	urls.add(url);
							}
						}
					}
				}
			}
			if(tag instanceof hasSWFTags)	getURLs(((hasSWFTags)tag).getTags() ,urls);
		}
	}
}
