/*
 * Copyright Kilo project team, 2004. All rights reserved.
 */
package shared;

import java.awt.Graphics2D;
import java.awt.*;
import java.awt.image.BufferedImage;
import shared.NotLinkedException;

/**
 * Parent class to RouteRenderer and MapRenderer, used for all rendered representations. The private methods govern the look of all maps.
 * 
 * @author Alaric [ajrn2]
 * @version 1.1
 */
public abstract class Renderer
{
	protected Graphics2D graphics;
	protected Color fgColour;
	protected Color bgColour;
	protected Position mapOrigin;
	protected float mapScale;
	
	public static final int MAPX = Constants.IMAGE_SIZE_X;
	public static final int MAPY = Constants.IMAGE_SIZE_Y;
	
	/**
	 * ABSTRACT method, used as the method to draw the map, each subclass will provide its own render method that utilises common Renderer private methods.
	 * 
	 * 
	 * @param o an object containing the map data, each child class will define its own methods of interpreting this object
	 * @param origin intended origin of the map to be rendered a a Position object
	 * @param scale intended scale of the map to be renderd as an int
	 * @return a MapImage object containing all the necessary data
	 */
	abstract public MapImage render(Object o, Position origin, float scale) throws NotLinkedException;
	
	
	protected Graphics2D getG(){
		return this.graphics;
	}
	
	protected void setG(Graphics2D g){
		this.graphics=g;
	}
	
	/**
	 * A method for adding the background image prior to any rendering.
	 * 
	 * @since 1.0
	 * @param im an Image object to be set as the background
	 */
	protected void addBG(Image im){
		//to add an image to the BG
		BufferedImage imBuffered = (BufferedImage)im;
		this.graphics.drawImage(im, 0, 0, null);
	}
	
	/**
	 * Protected method for drawing a road between two Position objects
	 * 
	 * @param one a Position object describing the start point of the road to be drawn
	 * @param two a Position object describing the end point of the road to be drawn
	 */
	protected void drawRoad(Position one, Position two){
		//just call more generalised version
		drawRoad(one, two, this.fgColour);
	}
	
	/**
	 * Method for returning a float for the line width for the given scale, varies on the boolean argument determining if it's a main road or not too. Passed as an argument to the BasicStroke constructor. [INTERNAL]
	 * 
	 * @since 1.1
	 * @param mainRoad a boolean determining if it's counted as a main or side road side roads are thinner
	 * @return a float indicating the width for the BasicStroke constructor
	 */
	protected float getRoadWidth(boolean mainRoad){
		//float result=0.0f;
		int j = (mainRoad)? 32 : 16;
		for(int i = 0; i < this.mapScale; i++){
			j>>=1;
			if(j<=0) j=1;
		}
		return j*1.0f;
	}
	
	/**
	 * Method for returning an int for the line width for the given scale, varies on the boolean argument determining if it's a main road or not too. Passed as an argument to the BasicStroke constructor. [INTERNAL]
	 * 
	 * @since 1.1
	 * @param mainRoad a boolean determining if it's counted as a main or side road side roads are thinner
	 * @return a float indicating the width for the BasicStroke constructor
	 */
	protected int getIntRoadWidth(boolean mainRoad){
		//float result=0.0f;
		int j = (mainRoad)? 32 : 16;
		for(int i = 0; i < this.mapScale; i++){
			j>>=1;
			if(j<=0) j=1;
		}
		return j;
	}
	
	/**
	 * Protected wrapper method for drawing a road between two Position objects of a given colour.
	 * 
	 * @since 1.0
	 * @param one a Position object describing the start point of the road to be drawn
	 * @param two a Position object describing the end point of the road to be drawn
	 * @param c the colour as a Color object of the road to be drawn
	 */
	protected void drawRoad(Position one, Position two, Color c){
		drawRoad(one, two, c, true);
	}
	
	
	/**
	 * Protected method for drawing a road between two Position objects of a given colour and road significance.
	 * 
	 * @since 1.1
	 * @param one a Position object describing the start point of the road to be drawn
	 * @param two a Position object describing the end point of the road to be drawn
	 * @param c the colour as a Color object of the road to be drawn
	 * @param majorMinor a boolean describing if the road is a major or minor road, major is true.
	 */
	protected void drawRoad(Position one, Position two, Color c, boolean majorMinor){
		//draw road with colour
		Position[] mapPositions = determineMapPositions(one, two);
		if(mapPositions==null||mapPositions[0]==null||mapPositions[1]==null){
			return;
		}
		else{
			//the road should be drawn
			//translate to pixel values
			Position onePixelCoords = translationToPixels(mapPositions[0]);
			Position twoPixelCoords = translationToPixels(mapPositions[1]);
			
			//store the old colour and set it to the new one
			Color temp = this.graphics.getColor();
			this.graphics.setColor(c);
			//draw the line for the road
			//MAKE A LOT MORE FANCY IF NECESSARY
			boolean fullRoadSize = true;
			if(!majorMinor) fullRoadSize = false;
			this.graphics.setStroke(new BasicStroke(this.getRoadWidth(fullRoadSize)));
			this.graphics.drawLine(onePixelCoords.getX(),onePixelCoords.getY(),twoPixelCoords.getX(),twoPixelCoords.getY());
			//System.out.println("Road:P1x="+one.getX()+" P1y="+one.getY()+" P2x="+two.getX()+" P2y="+two.getY()+" pC1x="+onePixelCoords.getX()+" pC1y="+onePixelCoords.getY()+" pC2x="+twoPixelCoords.getX()+" pC2y="+twoPixelCoords.getY());
			this.graphics.setStroke(new BasicStroke(1.0f));
			//reset the colour
			this.graphics.setColor(temp);
		}
		return;
	}
	
	/**
	 * A method for adding a vertex to the map.
	 * 
	 * @author Alaric [ajrn2]
	 * @since 1.0
	 * @param v a Position object describing the location of the vertex to be drawn
	 */
	protected void drawVertex(Position v){
		drawVertex(v, this.fgColour);
	}
	
	/**
	 * A method for adding a vertex to the map.
	 * 
	 * @author Alaric [ajrn2]
	 * @since 1.0
	 * @param c a Color object labelling the colour of the intersection to draw
	 * @param v a Position object describing the location of the vertex to be drawn
	 */
	protected void drawVertex(Position v, Color c){
		//just for nodes
		//translate the coordinates into Pixel coordinates
		Position pixelCoords = translationToPixels(v);
		if(pixelCoords==null) return;
		if(!isOnMap(pixelCoords)) return;
		//System.out.println("Vertex:Px="+v.getX()+" Py="+v.getY()+" pCx="+pixelCoords.getX()+" pCy="+pixelCoords.getY());
		//store the old colour and set it to the new one
		Color temp = this.graphics.getColor();
		this.graphics.setColor(c);
		this.graphics.drawOval((pixelCoords.getX()),(pixelCoords.getY()),1,1);
		this.graphics.setColor(temp);
	}
	
	/**
	 * A method for adding a vertex to the map with a String label.
	 * 
	 * @param v a Position object describing the location of the vertex to be drawn
	 * @param label a String object containing a label for the vertex
	 */
	protected void drawVertex(Position v, String label){
		//for nodes on the route, numbered etc.
		drawVertex(v);
	}
	
	/**
	 * A function that returns the raw coordinate Positions that need to be rendered to the map, they will need conversion to pixels by the translationToPixels method.
	 * 
	 * @author Alaric [ajrn2]
	 * @since 1.0
	 * @param pOne a Position object storing the beginning of the road
	 * @param pTwo a Position object storing the end of the road
	 * @return a Position array containing the two raw Positions to draw on the map, returns null if not to be drawn
	 */
	private Position[] determineMapPositions(Position pOne, Position pTwo){
		Position[] returnValue = new Position[2];//return array
		int x1,x2,y1,y2;//some ints to store results
		//float dxbydy, dybydx; //to store the gradients
		
		int bndx0 = this.mapOrigin.getX();
		int bndx1 = this.mapOrigin.getX()+(int)(MAPX*this.mapScale);
		
		int bndy0 = this.mapOrigin.getY();
		int bndy1 = this.mapOrigin.getY()+(int)(MAPY*this.mapScale);
		
		//check if both positions are on the map already
		if(isOnMap(pOne)&&isOnMap(pTwo)){
			//both on the map already, we don't need to worry about finding nearest boundary points.
			x1=pOne.getX();
			x2=pTwo.getX();
			y1=pOne.getY();
			y2=pTwo.getY();
			returnValue[0]=new Position(x1, y1);
			returnValue[1]=new Position(x2, y2);
			//System.out.println("LINE:162:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
			return returnValue;
		}//end both on map already check
		
		
		//if((int)Math.abs(pOne.getX()-pTwo.getX())>(int)Math.abs(pOne.getY()-pTwo.getY())){//if dx > dy
		if(isOnMap(pOne)){//pOne is on map, pTwo is known not to be
			if((pOne.getX()==pTwo.getX())&&(pOne.getY()==pTwo.getY())){
				//same point
				x1=pOne.getX();
				x2=pTwo.getX();
				y1=pOne.getY();
				y2=pTwo.getY();
				returnValue[0]=new Position(x1, y1);
				returnValue[1]=new Position(x2, y2);
				//System.out.println("LINE:177:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
				return returnValue;
			}//endif at same point
			else{//beginelse not at same point
				if((pOne.getX()==pTwo.getX())||(pOne.getY()==pTwo.getY())){//checks vertical/horizontal first
					if(pOne.getX()==pTwo.getX()){//vertical
						if(pOne.getY()>pTwo.getY()){//going upwards
							x1=pOne.getX();
							y1=pOne.getY();
							x2=pTwo.getX();
							y2=this.mapOrigin.getY();//y2=0;
							returnValue[0]=new Position(x1, y1);
							returnValue[1]=new Position(x2, y2);
							//System.out.println("LINE:190:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
							return returnValue;
						}
						else{//going downwards
							x1=pOne.getX();
							y1=pOne.getY();
							x2=pTwo.getX();
							y2=this.mapOrigin.getY()+(int)(MAPY*this.mapScale);//y2=MAPY;
							returnValue[0]=new Position(x1, y1);
							returnValue[1]=new Position(x2, y2);
							//System.out.println("LINE:200:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
							return returnValue;
						}
					}//endif vertical
					else{//horizontal Y=Y
						if(pOne.getX()>pTwo.getX()){//going left
							x1=pOne.getX();
							y1=pOne.getY();
							x2=this.mapOrigin.getX();//x2=0;
							y2=pTwo.getY();
							returnValue[0]=new Position(x1, y1);
							returnValue[1]=new Position(x2, y2);
							//System.out.println("LINE:212:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
							return returnValue;
						}
						else{//going right
							x1=pOne.getX();
							y1=pOne.getY();
							x2=this.mapOrigin.getX()+(int)(MAPX*this.mapScale);//x2=MAPX;
							y2=pTwo.getY();
							returnValue[0]=new Position(x1, y1);
							returnValue[1]=new Position(x2, y2);
							//System.out.println("LINE:222:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
							return returnValue;
						}
					}//endelse horizontal
				}
				else{//at a funny angle - grr
					returnValue = lineIntersectionDetector(pOne,pTwo,1);
				}//endelse at a funny angle
			}//endelse not at same point
		}//endif pOne map check
		else{//pTwo may be on map or neither will be
			if(isOnMap(pTwo)){//pTwo is on the map to be rendered
				if((pOne.getX()==pTwo.getX())&&(pOne.getY()==pTwo.getY())){
					//same point
					x1=pOne.getX();
					x2=pTwo.getX();
					y1=pOne.getY();
					y2=pTwo.getY();
					returnValue[0]=new Position(x1, y1);
					returnValue[1]=new Position(x2, y2);
					//System.out.println("LINE:242:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
					return returnValue;
				}//endif at same point
				else{//beginelse not at same point
					if((pOne.getX()==pTwo.getX())||(pOne.getY()==pTwo.getY())){//checks vertical/horizontal first
						if(pOne.getX()==pTwo.getX()){//vertical
							if(pOne.getY()<pTwo.getY()){//going upwards
								x1=pOne.getX();
								y1=this.mapOrigin.getY();//y1=0;
								x2=pTwo.getX();
								y2=pTwo.getY();
								returnValue[0]=new Position(x1, y1);
								returnValue[1]=new Position(x2, y2);
								//System.out.println("LINE:255:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
								return returnValue;
							}
							else{//going downwards
								x1=pOne.getX();
								y1=this.mapOrigin.getY()+(int)(MAPY*this.mapScale);//y1=MAPY;
								x2=pTwo.getX();
								y2=pTwo.getY();
								returnValue[0]=new Position(x1, y1);
								returnValue[1]=new Position(x2, y2);
								//System.out.println("LINE:265:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
								return returnValue;
							}
						}//endif vertical
						else{//horizontal Y=Y
							if(pOne.getX()<pTwo.getX()){//going left
								x1=this.mapOrigin.getX();//x1=0;
								y1=pOne.getY();
								x2=pTwo.getX();
								y2=pTwo.getY();
								returnValue[0]=new Position(x1, y1);
								returnValue[1]=new Position(x2, y2);
								//System.out.println("LINE:277:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
								return returnValue;
							}
							else{//going right
								x1=this.mapOrigin.getX()+(int)(MAPX*this.mapScale);//x1=MAPX;
								y1=pOne.getY();
								x2=pTwo.getX();
								y2=pTwo.getY();
								returnValue[0]=new Position(x1, y1);
								returnValue[1]=new Position(x2, y2);
								//System.out.println("LINE:287:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
								return returnValue;
							}
						}//endelse horizontal
					}
					else{//at a funny angle - grr
						
						returnValue = lineIntersectionDetector(pOne,pTwo,2);
					}//endelse at a funny angle
				}//endelse not at same point
			}//endif pTwo onMap
			else{//neither exists on map to be rendered
				//check for horizontality and verticality
				if((pOne.getX()==pTwo.getX())&&(pOne.getY()==pTwo.getY())){
					//same point
					x1=pOne.getX();
					x2=pTwo.getX();
					y1=pOne.getY();
					y2=pTwo.getY();
					returnValue[0]=new Position(x1, y1);
					returnValue[1]=new Position(x2, y2);
					//System.out.println("LINE:242:"+returnValue[0].getX()+" "+returnValue[0].getY()+" "+returnValue[1].getX()+" "+returnValue[1].getY()+" ");//DEBUG
					return returnValue;
				}//endif at same point
				else{//beginelse not at same point
					if((pOne.getX()==pTwo.getX())||(pOne.getY()==pTwo.getY())){//checks vertical/horizontal first
						if(pOne.getX()==pTwo.getX()){//vertical
							if(pOne.getX()>=bndx0&&pOne.getX()<=bndx1){
								if(pOne.getY()>=bndy1&&pTwo.getY()<=bndy0){
									returnValue[0]=new Position(pOne.getX(), bndy0);
									returnValue[1]=new Position(pOne.getX(), bndy1);
								}
								else if(pOne.getY()<=bndy0&&pTwo.getY()>=bndy1){
									returnValue[0]=new Position(pOne.getX(), bndy0);
									returnValue[1]=new Position(pOne.getX(), bndy1);
								}
							}
							return returnValue;
						}//endif vertical
						else{//horizontal Y=Y
							if(pOne.getY()>=bndy0&&pOne.getY()<=bndy1){
								if(pOne.getX()>=bndx1&&pTwo.getX()<=bndx0){
									returnValue[0]=new Position(bndx0, pOne.getY());
									returnValue[1]=new Position(bndx1, pOne.getY());
								}
								else if(pOne.getX()<=bndx0&&pTwo.getX()>=bndx1){
									returnValue[0]=new Position(bndx0, pOne.getY());
									returnValue[1]=new Position(bndx1, pOne.getY());
								}
							}
							return returnValue;
						}//endelse horizontal
						
					}
					else{//at a funny angle - grr
						returnValue = lineIntersectionDetector(pOne,pTwo,0);
						
					}//endelse at a funny angle
				}//endelse not at same point
				//returnValue = lineIntersectionDetector(pOne,pTwo,0);
			}//endelse neither on map
		}//end else pOne on map
		//}//endif dx dy check
		//else{//if dx=dy or dy>dx
		
		//}//endelse dx-dy check
		
		
		//give the results back.
		return returnValue;
	}
	
	/**
	 * A method for translating from the data coordinates to the scaled and shifted coordinates used to actually render onto the map
	 * 
	 * @author Alaric [ajrn2]
	 * @since 1.0
	 * @param p a Position object for translation to the pixel coordinate system of the canvas
	 * @return a Position object based around the pixels to be displayed
	 */
	protected Position translationToPixels(Position p){
		if(p==null) return null;
		else return new Position((int)((double)((double)p.getX()-(double)this.mapOrigin.getX())/(double)this.mapScale),(int)((double)((double)p.getY()-(double)this.mapOrigin.getY())/(double)this.mapScale));
	}
	
	
	
	/**
	 * Takes two Position objects and an int and works out the intersections with the boundaries of the map.
	 * 
	 * @author Alaric [ajrn2]
	 * @since 1.0
	 * @param pOne position of one end of the road
	 * @param pTwo position of the other end of the road
	 * @param whichIsOnMap an int to say which Position is already on the map (0=neither, 1=One, 2=Two)
	 * @return a Position array containing the Positions of where it should be rendered to on a map
	 */
	private Position[] lineIntersectionDetector(Position pOne, Position pTwo, int whichIsOnMap){
		Position[] returnValue = new Position[2];//return array
		
		//define bounding box
		int x0 = this.mapOrigin.getX();
		int x1 = this.mapOrigin.getX()+(int)(MAPX*this.mapScale);
		
		int y0 = this.mapOrigin.getY();
		int y1 = this.mapOrigin.getY()+(int)(MAPY*this.mapScale);
		
		boolean x0i=false;
		boolean x1i=false;
		boolean y0i=false;
		boolean y1i=false;
		
		//allocate intersection points
		int ix0,ix1,iy0,iy1;
		
		//get the points in a more usable form
		int ax = pOne.getX();
		int ay = pOne.getY();
		
		int bx = pTwo.getX();
		int by = pTwo.getY();
		
		
		//check for intersections on left edge (x0)
		ix0=(int)(ay + (double)((double)((double)(x0-ax)/(double)(bx-ax)))*(by-ay));
		if(ix0 >= y0 && ix0<=y1){
			//edge intersects
			x0i=true;
		}
		
		//check for intersections on right edge (x1)
		ix1=(int)(ay + (double)((double)((double)(x1-ax)/(double)(bx-ax)))*(by-ay));
		if(ix1 >= y0 && ix1<=y1){
			//edge intersects
			x1i=true;
		}
		
		//top edge
		iy0=(int)(ax + (double)((double)((double)(y0-ay)/(double)(by-ay)))*(bx-ax));
		if(iy0>=x0 && iy0<=x1){
			y0i=true;
		}
		
		//bottom edge
		iy1=(int)(ax + (double)((double)((double)(y1-ay)/(double)(by-ay)))*(bx-ax));
		if(iy1>=x0 && iy1<=x1){
			y1i=true;
		}
		
		//System.out.println("FUNKYINTERSECTIONS: ix0="+ix0+" ix1="+ix1+" iy0="+iy0+" iy1="+iy1);
		
		if(whichIsOnMap==0){
			//check they aren't both off the same side of the map first
			if((ay<y0&&by<y0)||(ay>=y1&&by>=y1)||(ax<x0&&bx<x0)||(ax>=x1&&bx>=x1)) return null;
			
			if(x0i==true){
				returnValue[0]=new Position(x0,ix0);
			}
			if(x1i==true){
				returnValue[((returnValue[0]==null)? 0 : 1)]=new Position(x1,ix1);
			}
			if(y0i==true){
				returnValue[((returnValue[0]==null)? 0 : 1)]=new Position(iy0, y0);//new Position(y0,iy0);//OLD
			}
			if(y1i==true){
				returnValue[((returnValue[0]==null)? 0 : 1)]=new Position(iy1, y1);//new Position(y1,iy1);//OLD
			}
			
		}
		else{
			if(whichIsOnMap==1){//position 1
				if(bx>ax&&by>ay){//y1 or x1 exit
					if(x1i==true){
						returnValue[0]=new Position(x1,ix1);//System.out.println("ax1y1:x1");
					}
					else if(y1i==true){
						returnValue[0]=new Position(iy1, y1);//System.out.println("ax1y1:y1");
					}
				}
				else if(bx>ax&&by<ay){//y0 or x1
					if(x1i==true){
						returnValue[0]=new Position(x1,ix1);//System.out.println("ax1y0:x1");
					}
					else if(y0i==true){
						returnValue[0]=new Position(iy0, y0);//System.out.println("ax1y0:y0");
					}
				}
				else if(bx<ax&&by<ay){//y0 or x0
					if(x0i==true){
						returnValue[0]=new Position(x0,ix0);//System.out.println("ax0y0:y1");
					}
					else if(y0i==true){
						//returnValue[0]=new Position(y0,iy0);System.out.println("ax0y0:y0");
						returnValue[0]=new Position(iy0, y0);//System.out.println("ax0y0:y0");
					}
				}
				else if(bx<ax&&by>ay){//x0 or y1
					if(x0i==true){
						returnValue[0]=new Position(x0,ix0);//System.out.println("ax0y1:x0");
					}
					else if(y1i==true){
						returnValue[0]=new Position(iy1, y1);//System.out.println("ax0y1:y1");
					}
				}
				returnValue[1]=new Position(ax, ay);
			}
			else{//position two
				if(bx<ax&&by<ay){//y1 or x1 exit
					if(x1i==true){
						returnValue[0]=new Position(x1,ix1);
					}
					else if(y1i==true){
						returnValue[0]=new Position(iy1, y1);
					}
				}
				else if(bx<ax&&by>ay){//y0 or x1
					if(x1i==true){
						returnValue[0]=new Position(x1,ix1);
					}
					else if(y0i==true){
						returnValue[0]=new Position(iy0, y0);
					}
				}
				else if(bx>ax&&by>ay){//y0 or x0
					if(x0i==true){
						returnValue[0]=new Position(x0,ix0);
					}
					else if(y0i==true){
						returnValue[0]=new Position(iy0, y0);
					}
				}
				else if(bx>ax&&by<ay){//x0 or y1
					if(x0i==true){
						returnValue[0]=new Position(x0,ix0);
					}
					else if(y1i==true){
						returnValue[0]=new Position(iy1, y1);
					}
				}
				returnValue[1]=new Position(bx, by);
			}
		}
		//System.out.println("");
		return returnValue;
	}
	
	/**
	 * Returns a boolean indicating if the Position argument is on the map.
	 * @param p	a Position object 
	 * @return a boolean indicating if the Position argument exists on this map
	 */
	protected boolean isOnMap(Position p)
	{	
		//bastardised from the MapImage Class... let's hope there aren't any bugs transfered across
		if(p==null) return false;		
		if(((this.mapOrigin.getX()+this.mapScale* MAPX)>p.getX())&&(this.mapOrigin.getX()<=p.getX())){ //checks the width lies in acceptable bounds
			if(((this.mapOrigin.getY()+this.mapScale* MAPY)>p.getY())&&(this.mapOrigin.getY()<=p.getY())){ //checks the height lies within acceptable bounds
				return true;
			}
			else{
				return false;
			}
		}
		else{
			return false;
		}
	}
	
}

