package turgen.dtb;

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

/** Segment binarniho souboru*/
public class Segment implements Comparable {
    
    /**Datovy segment*/
    public static final int DATA_SEGMENT=0;
    /**INIT segment*/
    public static final int INIT_SEGMENT=1;
    /**RUN segment*/
    public static final int RUN_SEGMENT=2;
    /**RUNINIT segment*/
    public static final int RUNINIT_SEGMENT=3;
    
    /**Retezcove oznaceni typu segmentu*/
    static final String[] typeStrings={"DATA","INIT","RUN","RUNINIT"};
        
    /**Pocatecni adresa*/
    public int start;
    /**Koncova adresa*/
    public int stop;
    /**Typ segmentu*/
    public int type;
    /**Adresa odskoku pro inicializacni a spousteci segmenty*/
    public int jump;
    
    /**Adresa odskoku 2, jen pro RUN/INIT segmenty*/
    public int jump2;
    
    /**Data segmentu*/
    public int[] data;
    
    /**Nova instance
     *@param s Pocatecni adresa segmentu
     *@param st Koncova adresa segmentu
     *@param t Typ segmentu
     */
    
    public Segment(int s,int st,int t) {
        this(s,st,t,0,0);
    }
    
    /**Nova instance
     *@param s Pocatecni adresa segmentu
     *@param st Koncova adresa segmentu
     *@param t Typ segmentu
     *@param j Skokova adresa
     */
    
    public Segment(int s,int st,int t,int j) {
        this(s,st,t,j,0);
    }
    
    Segment(int s,int st,int t,int j,int j2) {
        start=s;
        stop=st;
        type=t;
        jump=j;
        jump2=j2;
        data=new int[st-s+1];
        if (type==Segment.RUN_SEGMENT || type==Segment.INIT_SEGMENT) {
            data[0]=jump % 256;
            data[1]=jump / 256;
        }
        if (type==Segment.RUNINIT_SEGMENT) {
            data[0]=jump % 256;
            data[1]=jump / 256;
            data[2]=jump2 % 256;
            data[3]=jump2 / 256;
        }
    }
    
    /** retezcova reprezentace segmentu
     *  @return retezcova reprezentace
     */
    public String toString() {
        String s1=Integer.toString(start);
        String s2=Integer.toString(stop);
        String s4=typeStrings[type];
        String s3="";
        switch (this.type) {
            case (Segment.INIT_SEGMENT): {
                s3=Integer.toString(jump);
                break;
            }
            case(Segment.RUN_SEGMENT): {
                s3=Integer.toString(jump);
                break;
            }
            case (Segment.RUNINIT_SEGMENT): {
                s3=Integer.toString(jump);
                s3+=",";
                s3+=Integer.toString(jump2);
            }
            
        }
        
        return s4+": "+s1+"-"+s2+" "+s3;
    }
    
    /** Porovnani dvou segmentu, porovnava se podle pocatecni adresy
     *  @param o Objekt se kterym se ma porovnavat
     */
    public int compareTo(Object o) {
        Segment x =(Segment)o;
        if (x.start<this.start) return +1;
        if (x.start==this.start) return 0; else return -1;
    }
    
    public int[] getFullData() {
        
        int[] retArray = new int[data.length+4];
        retArray[0]=start % 256;
        retArray[1]=start / 256;
        retArray[2]=stop % 256;
        retArray[3]=stop / 256;
        System.arraycopy(data,0,retArray,4,data.length);
        
        return retArray;
    }
}
