package dynamic.common;

import java.io.IOException;
import java.net.Authenticator;
import java.util.ArrayList;

/**
 * Encapsulates a report from teachdb, allowing individual fields and
 * records to be queried.
 */
public class TeachdbReport {

    public ArrayList<String> headers = new ArrayList<String>();
    public ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();

    ArrayList<Boolean> filter_includes = new ArrayList<Boolean>();
    public boolean filtered = false;

    public static void main(String[] args) throws IOException {
        LoginHandler.login();
//        TeachdbReport rep = new TeachdbReport("https://teachdb.doc.ic.ac.uk/db/viewtab?table=Degree&arg0=%25&arg1=&arg2=&arg3=&arg4=&arg5=&arg6=");
        TeachdbReport rep = new TeachdbReport("https://teachdb.doc.ic.ac.uk/db/1213/viewtab?table=Degree&arg0=%25&arg1=&arg2=&arg3=&arg4=&arg5=&arg6=");
        System.out.println(rep);
        rep.filter("Code","bc"); System.out.println(rep);
    }

    public TeachdbReport(String url){

        // get the page
        Authenticator.setDefault(new MyAuthenticator());
        String page_str = ContentGrabber.GetWebContentSimple(url);

        // get the table
        int table_start = page_str.lastIndexOf("<table");
        int table_end = page_str.lastIndexOf("</table>");
        String table = page_str.substring(table_start, table_end);

        // get the rows
        ArrayList<String> rows = new ArrayList<String>();
        String[] split = table.split("<tr");
        for (String s : split) rows.add(s);

        // store row data
        headers = analyseRowData(rows.get(1));
        for (int i = 3; i < rows.size(); i++) {
            data.add(analyseRowData(rows.get(i)));
            filter_includes.add(true);
        }

    }

    private ArrayList<String> analyseRowData(String row) {
        ArrayList<String> res = new ArrayList<String>();
        String[] split = row.split("<td");
        for (int i = 2; i < split.length; i++) {
            String s = split[i];
            int field_start = s.indexOf('>') + 1;
            String data = s.substring(field_start);
            int td_end = data.indexOf("</td>");
            if(td_end >= 0)
                data = data.substring(0,td_end);

            // remove link tags
            int atag = data.indexOf("<a");
            if(atag >= 0){
                field_start = data.indexOf(">",atag) + 1;
                int field_end = data.indexOf("<",field_start);
                data = data.substring(field_start,field_end);
            }

            res.add(data.trim());
        }
        return res;
    }

    private int getIndexOf(String lookup_field, String lookup_value) {
        for (int i = 0; i < getRowCount(); i++) {
            if(getDataAt(lookup_field, i).equals(lookup_value))
                return i;
        }
        return -1;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (String s : headers) sb.append(s + "|");
        sb.append("\n");
        for (int i = 0; i < getRowCount(); i++) {
            for (String h : headers) sb.append(getDataAt(h, i) + "|");
            sb.append("\n");
        }
        return new String(sb);
    }

    ///////////////////////////////////////////////////////////////////////
    // GETTERS
    ///////////////////////////////////////////////////////////////////////
    public int getRowCount(){
        if(filtered){
            int count = 0;
            for (Boolean b : filter_includes) {
                if(b) count++;
            }
            return count;
        }
        return data.size();
    }


    public String getDataAt(String field, int row){
        int field_index = headers.indexOf(field);
        if(filtered) {
            int index = 0;
            int found = 0;
            while(!filter_includes.get(index) || ++found <= row)
                index++;
            return data.get(index).get(field_index);
        }
        return data.get(row).get(field_index);
    }

    public ArrayList<String> getAllData(String field){
        int field_index = headers.indexOf(field);
        ArrayList<String> res = new ArrayList<String>();
        for (int i = 0; i < data.size(); i++) {
            if(filter_includes.get(i))
                res.add(data.get(i).get(field_index));
        }
        return res;
    }

    public String lookupData(String lookup_field, String lookup_value, String return_field) {
        return getDataAt(return_field, getIndexOf(lookup_field, lookup_value));
    }

    ///////////////////////////////////////////////////////////////////////
    // FILTERING
    ///////////////////////////////////////////////////////////////////////
    public void filter(String field, String value){
        int field_index = headers.indexOf(field);
        for (int i = 0; i < filter_includes.size(); i++)
            if(filter_includes.get(i) && !data.get(i).get(field_index).equals(value))
                filter_includes.set(i,false);
        filtered = true;
    }

    public void filterClear(){
        for (int i = 0; i < filter_includes.size(); i++) filter_includes.set(i,true);
        filtered = false;
    }


}






