package PrintGame;

import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;
import java.lang.Integer;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URI;
import java.io.File;
import java.net.URISyntaxException;


public class LabyrinthXMLContentHandler extends DefaultHandler
{

  private String temp_labyrinth_data_;
  private String current_tag_;

  private String level_name_;
  //Labyrinth Dimension
  private int width_;
  private int height_;
  //Load Labyrinth Options
  private boolean is_load_labyrinth_;
  private char start_symbol_;
  private char wall_symbol_;
  private char diamond_symbol_;
  private char way_symbol_;
  private char zero_symbol_;
  private char one_symbol_;
  private char two_symbol_;
  private char three_symbol_;
  private Direction starting_direction_;
  private char[][] labyrinth_data_;
  //Create Labyrinth Options
  private boolean is_create_labyrinth_;
  private int diamonds_;
  private int way_cells_;
  private int min_way_lenght_;
  private int max_way_lenght_;
  private int build_angles_;
  private int build_trees_;
  private int build_loops_;
  private int build_places_;
  //Style Options
  private boolean is_style_;
  private boolean labyrinth_field_;
  private boolean is_instruction_list_;
  private String wall_picture_;
  private String way_picture_;
  private String robot_picture_;
  private String diamond_picture_;
  private String start_picture_;
  private String instruction_file_name_;
  private URL document_base_;

  public LabyrinthXMLContentHandler()
  {
    document_base_=null;
    width_=0;
    height_=0;
    start_symbol_= 0;
    wall_symbol_= 0;
    diamond_symbol_=0;
    way_symbol_= 0;
    zero_symbol_= 0;
    one_symbol_= 0;
    two_symbol_= 0;
    three_symbol_= 0;
    starting_direction_= new Direction();
    temp_labyrinth_data_= new String();
    current_tag_= new String();
    level_name_=new String();
    diamonds_ = 0;
    way_cells_ = 0;
    min_way_lenght_ = 0;
    max_way_lenght_ = 0;
    build_angles_ = 0;
    build_trees_ = 0;
    build_loops_ = 0;
    build_places_ = 0;
    is_load_labyrinth_=false;
    is_create_labyrinth_=false;
    is_style_=false;
    labyrinth_field_=false;
    is_instruction_list_=false;
  }

  public void setDocumentBase(URL document_base)
  {
    document_base_=document_base;
  }

/**-----------------------------------------------------------------------------
 *Receive notification of the beginning of the document.
 */
  public void startDocument()
  {
    //nothing to do here.
  }

/**-----------------------------------------------------------------------------
 *Receive notification of the start of an element.
 *@param attributes - The specified or defaulted attributes.
 *@param localName - The local name (without prefix),
 *or the empty string if Namespace processing is not being performed.
 *@param qualName - The qualified name (with prefix),
 *or the empty string if qualified names are not available.
 */

  public void startElement(String uri, String localName, String qualName, Attributes attribs)
  {
    current_tag_ = qualName;
    if (current_tag_.equals(new String(TagName.LABYRINTH)))
    {
      is_load_labyrinth_= true;
    }

    else if (current_tag_.equals(new String(TagName.CREATE)))
    {
      is_create_labyrinth_= true;
    }

    else if (current_tag_.equals(new String(TagName.STYLE)))
    {
      is_style_= true;
    }
  }

/**-----------------------------------------------------------------------------
 *Receive notification of character data inside an element.
 *@param charArray - The characters.
 *@param start - The start position in the character array.
 *@param length - The number of characters to use from the character array.
 */
  public void characters(char[] charArray, int start, int length)
  {
    if(current_tag_.length() > 0)
    {
      String temp_string = new String(charArray, start, length);
      temp_string = temp_string.trim();

      if (current_tag_.equals(new String(TagName.NAME)))
      {
        level_name_=temp_string;
      }

      else if (current_tag_.equals(new String(TagName.WIDTH)))
      {
        width_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.HEIGHT)))
      {
        height_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.STARTSYMBOL)))
      {
        start_symbol_=temp_string.trim().charAt(0);
      }

      else if (current_tag_.equals(new String(TagName.WALLSYMBOL)))
      {
        wall_symbol_=temp_string.charAt(0);
      }

      else if (current_tag_.equals(new String(TagName.DIAMONDSYMBOL)))
      {
        diamond_symbol_=temp_string.charAt(0);
      }

      else if (current_tag_.equals(new String(TagName.WAYSYMBOL)))
      {
        way_symbol_=temp_string.charAt(0);
      }

      else if (current_tag_.equals(new String(TagName.ZEROSYMBOL)))
      {
        zero_symbol_=temp_string.charAt(0);
      }

      else if (current_tag_.equals(new String(TagName.ONESYMBOL)))
      {
        one_symbol_=temp_string.charAt(0);
      }

      else if (current_tag_.equals(new String(TagName.TWOSYMBOL)))
      {
        two_symbol_=temp_string.charAt(0);
      }

      else if (current_tag_.equals(new String(TagName.THREESYMBOL)))
      {
        three_symbol_=temp_string.charAt(0);
      }

      else if (current_tag_.equals(new String(TagName.STARTDIRECTION)))
      {
        try
        {
          if (temp_string.equals(new String(Direction.DIR_UP)))
          {
            starting_direction_.setDirection(Direction.DIRECTION_UP);
          }
          else if (temp_string.equals(new String(Direction.DIR_RIGHT)))
          {
            starting_direction_.setDirection(Direction.DIRECTION_RIGHT);
          }
          else if (temp_string.equals(new String(Direction.DIR_DOWN)))
          {
            starting_direction_.setDirection(Direction.DIRECTION_DOWN);
          }
          else if (temp_string.equals(new String(Direction.DIR_LEFT)))
          {
            starting_direction_.setDirection(Direction.DIRECTION_LEFT);
          }
        }
        catch(IllegalDirectionException exc)
        {

        }
      }

      else if (current_tag_.equals(new String(TagName.LABYRINTHFIELD)))
      {
        labyrinth_field_=true;
        if (temp_string.length() > 1)
        {
          temp_labyrinth_data_ = temp_labyrinth_data_ + temp_string + "\n";
        }
      }

      else if (current_tag_.equals(new String(TagName.DIAMONDS)))
      {
        diamonds_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.WAYCELLS)))
      {
        way_cells_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.MINWAYLENGHT)))
      {
        min_way_lenght_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.MAXWAYLENGHT)))
      {
        max_way_lenght_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.BUILDANGLES)))
      {
        build_angles_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.BUILDTREES)))
      {
        build_trees_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.BUILDLOOPS)))
      {
        build_loops_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.BUILDPLACES)))
      {
        build_places_=Integer.decode(temp_string).intValue();
      }

      else if (current_tag_.equals(new String(TagName.WALLPICTURE)))
      {
        wall_picture_= new String();
        wall_picture_=temp_string;
      }

      else if (current_tag_.equals(new String(TagName.WAYPICTURE)))
      {
        way_picture_= new String();
        way_picture_=temp_string;
      }

      else if (current_tag_.equals(new String(TagName.ROBOTPICTURE)))
      {
        robot_picture_= new String();
        robot_picture_=temp_string;
      }

      else if (current_tag_.equals(new String(TagName.DIAMONDPICTURE)))
      {
        diamond_picture_= new String();
        diamond_picture_=temp_string;
      }

      else if (current_tag_.equals(new String(TagName.STARTPICTURE)))
      {
        start_picture_= new String();
        start_picture_=temp_string;
      }

      else if (current_tag_.equals(new String(TagName.INSTRUCTIONFILE)))
      {
        try
        {
          URL new_url = new URL(document_base_,temp_string);

          //URI uri = new URI(new_url.toString());

          //File file = new File(uri);
          String instruction_file_name_ = new_url.toString();
          is_instruction_list_=true;
        }
        catch( MalformedURLException ex )
        {
          System.err.println(ex.getMessage());
        }
        /*catch( URISyntaxException ex )
        {
          System.err.println(ex.getMessage());
        }*/
      }
    }
  }

/**-----------------------------------------------------------------------------
 *Receive notification of the end of an element.
 *@param localName - The local name (without prefix), or the empty string if
 *Namespace processing is not being performed.
 *@param qName - The qualified XML 1.0 name (with prefix), or the empty string if
 *qualified names are not available.
 */
  public void endElement(String uri, String localName, String qualName)
  {
    current_tag_="";
  }

/**-----------------------------------------------------------------------------
 *Receive notification of the end of the document.
 */
  public void endDocument()
  {
    if(labyrinth_field_==true)
      convertLabyrinthData();
  }

/**-----------------------------------------------------------------------------
 * Generates a twodimensional character-array which is an ASCII representation
 * of the labyrinthfield.
 */
  private void convertLabyrinthData()
  {
    labyrinth_data_= new char[height_][width_];

    String[] rows = temp_labyrinth_data_.split("\n");

    for (int row_count=0; row_count<height_; row_count++)
    {
      temp_labyrinth_data_=rows[row_count].trim();
      for(int col_count =0; col_count<width_; col_count++)
      {
        labyrinth_data_[row_count][col_count]= temp_labyrinth_data_.charAt(col_count);
      }
    }
  }

  public String getLevelName()
  {
    return level_name_;
  }

  public int getWidth()
  {
    return width_;
  }

  public int getHeight()
  {
    return height_;
  }

  public char getStartSymbol()
  {
    return start_symbol_;
  }

  public char getWallSymbol()
  {
    return wall_symbol_;
  }

  public char getDiamondSymbol()
  {
    return diamond_symbol_;
  }

  public char getWaySymbol()
  {
    return way_symbol_;
  }

  public char getZeroSymbol()
  {
    return zero_symbol_;
  }

  public char getOneSymbol()
  {
    return one_symbol_;
  }

  public char getTwoSymbol()
  {
    return two_symbol_;
  }

  public char getThreeSymbol()
  {
    return three_symbol_;
  }

  public Direction getStartingDirection()
  {
    return starting_direction_;
  }

  public char[][] getLabyrinth()
  {
    return labyrinth_data_;
  }

  public int getNumDiamonds()
  {
    return diamonds_;
  }

  public int getNumWayCells()
  {
    return way_cells_;
  }

  public int getMinWayLenght()
  {
    return min_way_lenght_;
  }

  public int getMaxWayLenght()
  {
    return max_way_lenght_;
  }

  public int getBuildAngles()
  {
    return build_angles_;
  }

  public int getBuildTrees()
  {
    return build_trees_;
  }

  public int getBuildPlaces()
  {
    return build_places_;
  }

  public int getBuildLoops()
  {
    return build_loops_;
  }

  public String getWallPicture()
  {
    return wall_picture_;
  }

  public String getWayPicture()
  {
    return way_picture_;
  }

  public String getRobotPicture()
  {
    return robot_picture_;
  }

  public String getDiamondPicture()
  {
    return diamond_picture_;
  }

  public String getStartPicture()
  {
    return start_picture_;
  }

  public boolean isLoadLabyrinth()
  {
    return is_load_labyrinth_;
  }

  public boolean isCreateLabyrinth()
  {
    return is_create_labyrinth_;
  }

  public boolean isStyle()
  {
    return is_style_;
  }
  public boolean isInstructionList()
  {
    return is_instruction_list_;
  }

  public String getInstructionFileName()
  {
    return instruction_file_name_;
  }
}
