/*************************************************************************************

This file is part of FragMend.

Written by Florian Buchholz, Glenn Henderson, David Horvath, and Jeff Jones.

Copyright (c) 2006, Florian Buchholz, Glenn Henderson, David Horvath, and Jeff Jones.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.     
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.       
    * Neither the name of Florian Buchholz, Glenn Henderson, David Horvath, Jeff
      Jones, nor the names of its contributors may be used to endorse or promote
      products derived from this software without specific prior written
      permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*************************************************************************************/

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class Fragment {
	
	public static final int FIELD_NAME = 0;
	public static final int FIELD_PRINT_COUNT = 1;
	public static final int FIELD_ZERO_PADDED = 2;
	public static final int FIELD_JPG_HEADER = 3;
	public static final int FIELD_JPG_FOOTER = 4;
	public static final int FIELD_JPG_MARKERS = 5;
	public static final int FIELD_ZIP_HEADER = 6;
	public static final int FIELD_ZIP_FOOTER = 7;
	public static final int FIELD_HTML_HEADER = 8;
	public static final int FIELD_HTML_FOOTER = 9;
	public static final int FIELD_BRACKET_COUNT = 10;
	public static final int FIELD_ID = 11;
	public static final int FIELD_OFFICE_HEADER = 12;
	public static final int FIELD_OFFICE_FOOTER = 13;
	public static final int FIELD_SEQUENCE_COUNT = 14;
	public static final int FIELD_OFFICE_ROOTDIR = 15;
	
	private int id;
	private File source;
	private long source_byte_offset;
	private boolean contains_JPG_header;
	private boolean contains_JPG_footer;
	private boolean contains_ZIP_header;
	private boolean contains_ZIP_footer;
	private boolean contains_Office_header;
	private boolean contains_Office_footer;
	private boolean contains_Office_directory;
	private boolean contains_HTML_header;
	private boolean contains_HTML_footer;
	private boolean is_zero_padded;
	private int printable_characters;
	private int JPG_marker_count;
	private int bracket_count;
	private int consecutive_word_count;
		
	public Fragment(int id, File s, long offset) {
		this.id = id;
		this.source = s;
		this.source_byte_offset = offset;
		
		byte[] data = getData();
		
		this.contains_JPG_header = JPGUtilities.containsHeader(data);
		this.contains_JPG_footer = JPGUtilities.containsFooter(data);
		this.JPG_marker_count = JPGUtilities.getDataMarkerCount(data);
		this.contains_ZIP_header = ZIPUtilities.containsHeader(data);
		this.contains_ZIP_footer = ZIPUtilities.containsFooter(data);
		this.contains_HTML_header = HTMLUtilities.containsHeader(data);
		this.contains_HTML_footer = HTMLUtilities.containsFooter(data);
		this.bracket_count = HTMLUtilities.getBracketCount(data);
		this.contains_Office_header = OfficeUtilities.containsHeader(data);
		this.contains_Office_footer = OfficeUtilities.containsFooter(data);
		this.contains_Office_directory = OfficeUtilities.containsDirectory(data);
		this.is_zero_padded = DataUtilities.isZeroPadded(data);
		this.printable_characters = DataUtilities.printableAsciiCount(data);
		this.consecutive_word_count = OfficeUtilities.getSequenceCount(data);
	}

	public int getId() {
		return id;
	}
	
	public File getSource() {
		return source;
	}
	
	public boolean containsJPGHeader() {
		return contains_JPG_header;
	}
	
	public void setJPGHeaderFlag(boolean newVal) {
		this.contains_JPG_header = newVal;
	}
	
	public boolean containsJPGFooter() {
		return contains_JPG_footer;
	}
	
	public int getJPGMarkerCount() {
		return JPG_marker_count;
	}
	
	public void setJPGFooterFlag(boolean newVal) {
		this.contains_JPG_footer = newVal;
	}

	public boolean containsZIPHeader() {
		return contains_ZIP_header;
	}
	
	public void setZIPHeaderFlag(boolean newVal) {
		this.contains_ZIP_header = newVal;
	}
	
	public boolean containsZIPFooter() {
		return contains_ZIP_footer;
	}
	
	public boolean containsHTMLHeader() {
		return contains_HTML_header;
	}
	
	public boolean containsHTMLFooter() {
		return contains_HTML_footer;
	}

	public boolean containsOfficeHeader() {
		return contains_Office_header;
	}
	
	public boolean containsOfficeRootDirectory() {
		return contains_Office_directory;
	}
		
	public boolean containsOfficeFooter() {
		return contains_Office_footer;
	}
	
	public int getBracketCount() {
		return bracket_count;
	}
	
	public boolean isZeroPadded() {
		return is_zero_padded;
	}
	
	public int getPrintableCount() {
		return printable_characters;
	}
	
	public int getSequenceCount() {
		return consecutive_word_count;
	}
	
	public String getName() {
		return "Sector " + id;
	}
	
	public byte[] getData() {
	
		FileInputStream input;
		
		int sector_size = FragMend.getSectorSize();
		
		byte[] retVal = new byte[sector_size];
		
		try {
			input = new FileInputStream(source);
			input.skip(source_byte_offset);
			int received = input.read(retVal);
			if (received < sector_size)
				System.err.println("Fragment.getData(): only read " + received + 
					" bytes from file " + source);
			input.close();
			
		}
		catch(FileNotFoundException fnf) {
			System.err.println("File not found: " + source);
			return null;
		}
		catch(IOException ioe) {
			System.err.println(ioe);
			return null;
		}
		return retVal;
		
	}
	
	public String toString(){
		return getName();
	}
	
	public void writeXML(OutputStreamWriter out, String indent) throws IOException {
		
		out.write(indent + "<fragment id=\"" + this.id + "\" offset=\"" + 
				this.source_byte_offset + "\"/>\n");
		
	}
}

