package com.brilliance.mda.runtime.mda.impl;

import com.brilliance.mda.runtime.mda.IDataGrid;
import com.fasterxml.jackson.annotation.JsonIgnore;

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

public class DataGrid implements IDataGrid, Serializable {

    protected List<String> rows = new ArrayList<>();
    protected List<String> initRows = new ArrayList<>();
    protected Map<String,Object> attrs = new HashMap<>();

    private boolean keepsort;

    @Override
    public void insertLine(int idx, String line) {
        if (idx <= 0 || idx > rows.size()) {
            rows.add(line);
            return;
        }
        if(line != null)
            rows.add(--idx,line);
    }

    @JsonIgnore
    public String getLine(int idx) {
        if(idx == 0) idx =1;
        idx--;
        if(idx >= rows.size())
            return "";
        return rows.get(idx);
    }

    @JsonIgnore
    @Override
    public String deleteLine(int idx) {
        if(idx == 0) idx =1;
        return rows.remove(--idx);
    }

    @Override
    public void sortLines() {
        Collections.sort(rows);
    }

    @Override
    public int countLines() {
        return rows.size();
    }
    @JsonIgnore
    @Override
    public int searchLine(String line) {
        if(line ==null) return 0;
        for (int i = 0; i <rows.size() ; i++) {
            if(rows.get(i) == null) continue;

            if(!keepsort && rows.get(i).toLowerCase().startsWith(line.toLowerCase())){
                return i+1;
            }
            if(keepsort && rows.get(i).startsWith(line)){
                return i+1;
            }
        }
        return 0;
    }

    @Override
    public void setRows(List<String> list) {
        this.rows.clear();
        rows.addAll(list);
    }

    @Override
    public List<String> getRows() {
        return rows;
    }

    @Override
    public void clearLines() {
        this.rows.clear();
    }

    @Override
    public void addLine(String line) {
        if(line != null)
            this.rows.add(line);
    }

    @JsonIgnore
    public void setLine(int idx, String line) {
        if(idx == 0) idx =1;
        if(line == null){
            return;
        }
        //String[] lines = line.split("[\\r\\n]{1,2}");
        String[] lines = new String[]{line};
        //计算替换区间
        int endIdx = idx +lines.length;
        for(int n=this.rows.size()+1;n<endIdx;n++){
            this.rows.add("");
        }

        for(int n=idx;n<endIdx;n++){
            this.rows.set(n-1,lines[n-idx]);
        }
    }

    @JsonIgnore
    public void loadLines(File file)throws IOException {
        BufferedReader br = null;
        rows.clear();
        try{
            br = new BufferedReader(new FileReader(file));
            String str = null;
            while((str = br.readLine())!=null){
                rows.add(str);
            }
        }catch (IOException e){
            rows.clear();
            throw e;
        }finally {
            if(br != null){
                br.close();
            }
        }
    }

    @JsonIgnore
    public void saveLines(File file)throws IOException{
        BufferedWriter br = null;
        try{
            if(!file.exists()){
                file.createNewFile();
            }
            br = new BufferedWriter(new FileWriter(file));
            for (String s : rows) {
                br.write(s);
                br.newLine();
            }
        }catch (Exception e){
            rows.clear();
            throw new RuntimeException(e);
        }
        finally {
            if(br != null){
                br.close();
            }
        }
    }

    @JsonIgnore
    public boolean isLinesChanged(){
        if(rows.size() != initRows.size())
            return true;
        for (int i = 0; i < initRows.size(); i++) {
            if(!initRows.get(i).equals(rows.get(i))){
                return true;
            }
        }
        return false;
    }

    @JsonIgnore
    public <T> void setAttribute(String attr,T stream){
        this.attrs.put(attr,stream);
    }

    @JsonIgnore
    public <T> T getAttribute(String attr){
        return (T)this.attrs.get(attr);
    }

    public boolean isKeepsort() {
        return keepsort;
    }

    public void setKeepsort(boolean keepsort) {
        this.keepsort = keepsort;
    }

}
