text:
package shift;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.TexturePaint;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class WorldPanel extends JPanel implements ActionListener, Runnable, ChangeListener
{
    private Timer tickTimer;
    private boolean drawWater = true;
    private int tempQuadrant, frameCount;
    private long startTime;
    public static double getFPS;
    public static int baseUnit = 75, baseMapWidth = 1050, baseMapHeight = 1050, baseMapRadius = baseMapWidth/2, baseMapThickness = 10;
    public static double baseStraightUnit = (double)baseUnit/Math.sqrt(2);

    public static double fps;
    public static double scale;
    public static int unit = 75, mapRadius = baseMapRadius, mapThickness = baseMapThickness;
    public static double straightUnit = (double)unit/Math.sqrt(2);
    public static final int screenWidth = Frame.screenWidth, screenHeight = Frame.screenHeight, fpsCap = 160;
    public static int mapWidth = 1050, mapHeight = 1050;
    public static int widthHalf = screenWidth/2, heightHalf = screenHeight/2, worldTilesWidth = mapWidth/unit, worldTilesHeight = mapHeight/unit, mapRadiusUnits = mapRadius/unit;//RADIUS GOES FROM CORNER TO CORNER
    public static int[][] mapPoints;
    public static double squareWidth = (double)mapWidth/Math.sqrt(2), squareRadius = (double)baseMapRadius/Math.sqrt(2);//straightUnit is the width and height of a single unit... Accidentally coded so that a unit was measured from corner to corner at 45 degrees
    public static double worldX, worldY;
    public static double rotation, rotationFraction, tempRotation, spin, spinCalc, radSpin;
    public static double getShrink;
    private UI ui;
    private double colorRotation = 0;
    public static BufferedImage grassImage, leavesImage;
    public static TexturePaint grassTexture, leavesTexture;;
    private Object loopNotify = new Object();
    private Thread thread;
    private JButton turnLeft, turnRight, resetLevel;
    RectPrism prism;
    Audio a = new Audio();
    private JSlider volumeSlider = new JSlider(JSlider.HORIZONTAL, -50, 50, 0);

    private JButton randomShapes;

    TileSorter ts;
    TileDrawer td;
    private TileDrawer2 td2 = new TileDrawer2();
    Input input = new Input();
    MouseInput mouseInput = new MouseInput(this);
    Player player = new Player(0, 0, 5);
    private LevelLoader levelLoader = new LevelLoader(player, this);
    private WaterRipple[] waterRipples = new WaterRipple[8];
    private Toolbox toolbox = new Toolbox(this, player);
    public WorldPanel()
    {
        //panel settings and nuts and bolts methods
        setBounds(0,0,screenWidth, screenHeight);
        setOpaque(true);
        setDoubleBuffered(true);
        addKeyListener(input);
        addMouseListener(mouseInput);
        addMouseWheelListener(mouseInput);

        //variable initialization
        initVariables();

        //add buttons
        initButtons();

        //"talk-to" instances created.
        ts = new TileSorter();
        td = new TileDrawer();

        try{
            grassImage = ImageIO.read(WorldPanel.class.getClassLoader().getResourceAsStream("Images/Grass5.png"));

            grassTexture = new TexturePaint(grassImage, new Rectangle(0, 0, 256, 256));

            leavesImage = ImageIO.read(WorldPanel.class.getClassLoader().getResourceAsStream("Images/Leaves3.png"));

            leavesTexture = new TexturePaint(leavesImage, new Rectangle((int)worldX, (int)worldY, leavesImage.getWidth(), leavesImage.getHeight()));
        }catch(Exception e)
        {
            System.out.println(e);
        }

        prism = new RectPrism(0, 0, 50, 1.0, 2.0, 100);
        tick();
        thread = new Thread(this);

        thread.start();
        tickTimer = new Timer(5, this);
        tickTimer.setActionCommand("tick");
        tickTimer.setRepeats(true);
        tickTimer.start();
    }

    private void initVariables()
    {
        worldX = screenWidth/2; worldY=3*screenHeight/5; rotation = Math.toRadians(75); spin = 0; spinCalc = spin+Math.PI + (Math.PI/4); radSpin = spinCalc - (Math.PI/2); tempQuadrant = spinQuadrant();
        mapPoints = mapTopPoints(spin, mapRadius);
        frameCount = 0;
        scale = 2.0;
        ui = new UI(this);
        //fillWaterRipples();

    }
    private void initButtons()
    {
        volumeSlider.addChangeListener(this);
        volumeSlider.setBounds(0, 0, 100, 50);
        volumeSlider.setVisible(false);
        add(volumeSlider);
        //setLayout(new FlowLayout());
        setLayout(null);
        randomShapes = new JButton("New Shapes");
        randomShapes.addActionListener(this);
        randomShapes.setActionCommand("randomShapes");
        randomShapes.setBounds(1200, 100, 100, 100);

        turnLeft = new JButton("<<");
        turnLeft.addActionListener(this);
        turnLeft.setActionCommand("turnLeft");
        turnLeft.setBounds((screenWidth/2)-150, screenHeight - 150, 100, 50);
        add(turnLeft);
        turnLeft.setVisible(false);

        turnRight = new JButton(">>");
        turnRight.addActionListener(this);
        turnRight.setActionCommand("turnRight");
        turnRight.setBounds((screenWidth/2)+50, screenHeight - 150, 100, 50);
        add(turnRight);
        turnRight.setVisible(false);

        resetLevel = new JButton("Reset Level");
        resetLevel.addActionListener(this);
        resetLevel.setActionCommand("resetLevel");
        resetLevel.setBounds(10, 120, 100, 50);
        add(resetLevel);
        resetLevel.setVisible(false);
        //add(randomShapes);
    }

    private AffineTransform findTranslation(AffineTransform at, BufferedImage bi) {
    Point2D p2din, p2dout;

    p2din = new Point2D.Double(0.0, 0.0);
    p2dout = at.transform(p2din, null);
    double ytrans = p2dout.getY();

    p2din = new Point2D.Double(0, bi.getHeight());
    p2dout = at.transform(p2din, null);
    double xtrans = p2dout.getX();

    AffineTransform tat = new AffineTransform();
    tat.translate(-xtrans, -ytrans);
    return tat;
  }

    public void addTile(Tile t){ts.addTile(t);}//necessary?

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        frameCount++;//band-aid way to make the FPS count not change too quickly to read -- only changes the FPS once frameCount reaches a certain number and is then reset. Could be fixed.
        startTime = System.nanoTime();

        //thread.interrupt();
        //thread = new Thread(this);
        //thread.start();
        //tick();

        colorRotation += Math.PI/5000.0;
        setBackground(new Color(0, 65 + (int)(Math.abs(100*Math.sin(colorRotation))), 198));
        Graphics2D g2 = (Graphics2D)g;
        g2.setStroke(Toolbox.worldStroke);

        //g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        //drawMap(g);
        //ArrayList<Tile> tempTile = ts.holdList;//create a temp list of held tiles to be drawn. Maybe is clunky for no reason, but was originally made to skirt the list being modified while it was drawn.

        stripeMap(g, spin);
        drawWater(g);

        td2.draw(g);

        fillBelowMap(g);
        if((double)(1/((System.nanoTime()-startTime)/1000000000.0)) > fpsCap)//limit FPS. sometimes gets a negative timeout thrown. FIX
        {
            try {
                //System.out.println("HI");
                Thread.sleep((long)((1000.0/(double)fpsCap) - ((System.nanoTime()-startTime)/1000000)));

            } catch (Exception ex) {
                Logger.getLogger(WorldPanel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        //player.draw(g);
        player.drawPlayersChain(g);
        player.drawTransparentPlayer(g);
        ui.draw(g);
        renderTextures();

        getFPS = (double)(1.0/((System.nanoTime() - startTime)/1000000000.0));

        //drawDebugInfo(g);//needs to go after sleeping since FPS is calculated here and it needs to happen last.
        if(frameCount > 20)
        {
            fps = (double)(1/((System.nanoTime()-startTime)/1000000000.0));
            frameCount = 0;
        }
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setFont(new Font("Futura", Font.PLAIN, 16));
        g.drawString("FPS: " + Integer.toString((int)fps), 30, 100);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);

        repaint();
    }

    private void renderTextures()
    {
        try{

            double rotationRequired = radSpin;
            double locationX = grassImage.getWidth()/2;
            double locationY = grassImage.getHeight()/2;
            AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);

            grassTexture = new TexturePaint(grassImage, new Rectangle((int)worldX, (int)worldY, (int)(scale*128), (int)(scale*128*getShrink)));

            leavesTexture = new TexturePaint(leavesImage, new Rectangle((int)worldX, (int)worldY, (int)(0.5*scale*leavesImage.getWidth()), (int)(0.5*scale*distortedHeight(rotation, leavesImage.getHeight()))));

            // Drawing the rotated image at the required drawing locations
            //g.drawImage(newGrass, drawLocationX, drawLocationY, null);

            /*
            //TexturePaint tempTexture = new TexturePaint(grassImage, new Rectangle((int)worldX, (int)worldY, (int)(straightUnit), (int)(straightUnit*getShrink)));
            TexturePaint tempTexture = new TexturePaint(grassImage, new Rectangle((int)worldX, (int)worldY, (int)(straightUnit), (int)(straightUnit)));
            BufferedImage tempImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);

            Graphics2D tg2 = tempImage.createGraphics();
            tg2.setPaint(tempTexture);
            tg2.fillRect(144,144,512,512);

            double rotationRequired = -(spin + (Math.PI/4.0));
            double locationX = 400;
            double locationY = 400;
            AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);

            tempImage = op.filter(tempImage, null);
            Graphics2D tg3 = tempImage.createGraphics();
            tg3.drawRect(0, 0, tempImage.getWidth() - 1, tempImage.getHeight() - 1);
            g.drawImage(tempImage.getScaledInstance(tempImage.getWidth(), (int)(tempImage.getHeight()*getShrink), Image.SCALE_AREA_AVERAGING), (int)worldX -tempImage.getWidth()/2, (int)(worldY - ((tempImage.getHeight()/2)*getShrink)), null);
            g.fillOval((int)(locationX + worldX -tempImage.getWidth()/2), (int)(locationY + worldY - ((tempImage.getHeight()/2)*getShrink)), 10, 10);
            //g.drawImage(tempImage.getScaledInstance(725, (int)(725*getShrink), Image.SCALE_AREA_AVERAGING), (int)(worldX - (362)), (int)(worldY - (getShrink*(362))), null);

            //grassTexture = new TexturePaint(tempImage, new Rectangle(0,0, screenWidth, (int)(screenWidth*getShrink)));

            //grassTexture = new TexturePaint(op.filter(tempImage, null), new Rectangle((int)worldX, (int)worldY, (int)screenWidth, (int)(screenHeight)));

            //grassTexture = new TexturePaint(op.filter(grassImage,null), new Rectangle((int)(worldX-((unit - straightUnit)*Math.cos(radSpin%(Math.PI/2.0)))), (int)(worldY+((unit - straightUnit)*Math.sin(radSpin%(Math.PI/2.0)))), (int)((Math.cos(radSpin%(Math.PI/2.0))*straightUnit) + (Math.sin(radSpin%(Math.PI/2.0))*straightUnit)), (int)(((Math.cos(radSpin%(Math.PI/2.0))*straightUnit) + (Math.sin(radSpin%(Math.PI/2.0))*straightUnit)) * getShrink)));
            //grassTexture = new TexturePaint(op.filter(grassImage,null), new Rectangle((int)(worldX-((unit - straightUnit)*Math.cos(radSpin%(Math.PI/2.0)))), (int)(worldY+((unit - straightUnit)*Math.sin(radSpin%(Math.PI/2.0)))), (int)straightUnit, (int)(straightUnit*getShrink)));
            //g.drawString("textureWidth: " + Integer.toString((int)((Math.cos(radSpin%(Math.PI/2.0))*straightUnit) + (Math.sin(radSpin%(Math.PI/2.0))*straightUnit))), 200, 200);
            */
        }catch(Exception e)
        {
            System.out.println(e);
        }
    }
    public static int[] getMouseUnitPos()//basically works by "unrotating" the world and applying the same algorithm to the position of the mouse along with it so that it can compare the unrotated mouse pos with the unrotated world pos. Works as intended.
    {
        double dx = (MouseInput.x-worldX)*shrink(rotation);//calculates unsquashed distance from the center of the world to the mouse ("unsquashing" it in the process so the calculation is what it would be on a flat world)
        double dy = MouseInput.y-worldY;//calculates unsquahsed distance from center of map to mouse.

        double radiusHeight = Math.sqrt(Math.pow(dx, 2)+Math.pow(dy, 2));//finds the radius of the oval's height (since circle is squashed by the amount the world is turned)
        double radiusWidth = radiusHeight/shrink(rotation);//finds the radius of the oval's width taking into account the squahsed world

        double theta = Math.atan2(-dy, dx);

        double unturneddx = radiusWidth*Math.cos(theta-radSpin);
        double unturneddy = radiusHeight*Math.sin(theta-radSpin);

        int[] giveReturn = {(int)(Math.ceil(unturneddx/straightUnit)),(int)(Math.ceil(unturneddy/(straightUnit*shrink(rotation))))};
        return giveReturn;
    }
    public static double[] getMouseUnitPosDouble()//basically works by "unrotating" the world and applying the same algorithm to the position of the mouse along with it so that it can compare the unrotated mouse pos with the unrotated world pos. Works as intended.
    {
        double dx = (MouseInput.x-worldX)*shrink(rotation);//calculates unsquashed distance from the center of the world to the mouse ("unsquashing" it in the process so the calculation is what it would be on a flat world)
        double dy = MouseInput.y-worldY;//calculates unsquahsed distance from center of map to mouse.

        double radiusHeight = Math.sqrt(Math.pow(dx, 2)+Math.pow(dy, 2));//finds the radius of the oval's height (since circle is squashed by the amount the world is turned)
        double radiusWidth = radiusHeight/shrink(rotation);//finds the radius of the oval's width taking into account the squahsed world

        double theta = Math.atan2(-dy, dx);

        double unturneddx = radiusWidth*Math.cos(theta-radSpin);
        double unturneddy = radiusHeight*Math.sin(theta-radSpin);

        double[] giveReturn = {unturneddx/straightUnit,unturneddy/(straightUnit*shrink(rotation))};
        return giveReturn;
    }
    private void drawMap(Graphics g)
    {
        g.setColor(Color.BLACK);

        g.drawPolygon(mapPoints[0], mapPoints[1], 4);

        int tempLowerPoints[][] = new int[2][4];
        for(int i = 0; i < 4; i++)
        {
            tempLowerPoints[0][i] = mapPoints[0][i];
            tempLowerPoints[1][i] = (int)(mapPoints[1][i]+distortedHeight(rotation, mapThickness));
        }

        for(int i = 0; i < 4; i++)//top left, top right, bottom right, bottom left
        {
            if(i != 3)
            {
                int[] xPoints = {mapPoints[0][i], mapPoints[0][i+1], mapPoints[0][i+1], mapPoints[0][i]};
                int[] yPoints = {mapPoints[1][i], mapPoints[1][i+1], (int)(mapPoints[1][i+1]+distortedHeight(rotation, mapThickness)), (int)(mapPoints[1][i]+distortedHeight(rotation, mapThickness))};
                g.drawPolygon(xPoints, yPoints, 4);
            }else{
                int[] xPoints = {mapPoints[0][i], mapPoints[0][0], mapPoints[0][0], mapPoints[0][i]};
                int[] yPoints = {mapPoints[1][i], mapPoints[1][0], (int)(mapPoints[1][0]+distortedHeight(rotation, mapThickness)), (int)(mapPoints[1][i]+distortedHeight(rotation, mapThickness))};
                g.drawPolygon(xPoints, yPoints, 4);
            }
        }
        //drawRotationLine(g);

    }
    private void drawDebugInfo(Graphics g)//draws important dev info.
    {
        g.setColor(Color.BLACK);
        g.setFont(new Font("Futura", Font.PLAIN, 12));
        for(int i = 0; i<4; i++)
        {
            g.drawString(i+"",mapPoints[0][i], mapPoints[1][i]);
        }
        g.drawString("Quadrant: " + Integer.toString(spinQuadrant()),125, 50);
        if(frameCount > 100)
        {
            fps = (double)(1/((System.nanoTime()-startTime)/1000000000.0));
            frameCount = 0;
        }
        g.drawString("FPS: " + Integer.toString((int)fps), 50, 50);
        //g.drawString("X: " + Double.toString(getMouseUnitPosDouble()[0]), MouseInput.x, MouseInput.y - 15);
        //g.drawString("Y: " + Double.toString(getMouseUnitPosDouble()[1]), MouseInput.x, MouseInput.y);
        g.drawString("Spin: "+Double.toString(radSpin), 100, 800);
        g.drawString("Scale: " + Double.toString(scale), 100, 775);
    }
    private void drawWater(Graphics g)
    {
        if(drawWater)
        {
            //Graphics2D g2 = (Graphics2D)g;
            g.setColor(new Color(30, 144, 255));
            //g2.setPaint(grassTexture);
            g.fillPolygon(mapPoints[0], mapPoints[1],4);
        }
    }

    private void fillBelowMap(Graphics g)
    {
        int tempLowerPoints[][] = new int[2][4];
        for(int i = 0; i < 4; i++)
        {
            tempLowerPoints[0][i] = mapPoints[0][i];
            tempLowerPoints[1][i] = mapPoints[1][i];//(int)(mapPoints[1][i]+distortedHeight(rotation, mapThickness));
        }
        int[] xPoints1 = {tempLowerPoints[0][getMapLeftCornerIndex()], tempLowerPoints[0][getMapMiddleCornerIndex()], tempLowerPoints[0][getMapMiddleCornerIndex()],tempLowerPoints[0][getMapLeftCornerIndex()]};
        int[] yPoints1 = {tempLowerPoints[1][getMapLeftCornerIndex()], tempLowerPoints[1][getMapMiddleCornerIndex()], screenHeight, screenHeight};

        int[] xPoints2 = {tempLowerPoints[0][getMapMiddleCornerIndex()], tempLowerPoints[0][getMapRightCornerIndex()], tempLowerPoints[0][getMapRightCornerIndex()], tempLowerPoints[0][getMapMiddleCornerIndex()]};
        int[] yPoints2 = {tempLowerPoints[1][getMapMiddleCornerIndex()], tempLowerPoints[1][getMapRightCornerIndex()], screenHeight, screenHeight};

        g.setColor(new Color(0, 65 + (int)(Math.abs(100*Math.sin(colorRotation))), 198));//g.setColor(new Color(30, 144, 255));

        g.fillPolygon(xPoints1, yPoints1, 4);
        g.fillPolygon(xPoints2, yPoints2, 4);
    }

    private int getMapLeftCornerIndex()
    {
        if(radSpin > 0 && radSpin <= Math.PI/2.0)
        {
            return 0;
        }else if(radSpin > Math.PI/2.0 && radSpin < Math.PI)
        {
            return 3;
        }else if(radSpin > Math.PI && radSpin < 3.0*Math.PI/2.0)
        {
            return 2;
        }else{
            return 1;
        }
    }

    private int getMapMiddleCornerIndex()
    {
        if(getMapLeftCornerIndex() != 3)
        {
            return getMapLeftCornerIndex() + 1;
        }else{
            return 0;
        }
    }

    private int getMapRightCornerIndex()
    {
        if(getMapMiddleCornerIndex() != 3)
        {
            return getMapMiddleCornerIndex() + 1;
        }else{
            return 0;
        }
    }

    private void stripeMap(Graphics g, double spinIn)//this is incredibly clunky with methods that don't always do what they should
    {
        if(!drawWater)
        {
            g.setColor(Color.BLACK);
            for(int i =0; i < 4; i++)
            {
                g.drawString("x" + Integer.toString(i) + ": "+ Integer.toString(mapPoints[0][i]),50, 75+(i*25));
                g.drawString("y" + Integer.toString(i) + ": "+ Integer.toString(mapPoints[1][i]), 130, 75+(i*25));
            }
            int iterations = mapWidth/unit;
            int[][] points = mapPoints;

            for(int i = 0; i < (mapWidth/unit); i++)
            {
                if(i == (mapWidth/unit)/2)
                {
                    g.setColor(Color.YELLOW);//y axis
                }else{
                    g.setColor(Color.BLACK);
                }

                g.drawLine((int)(points[0][0] + i*(getdx(points)/iterations)), (int)(points[1][0]+(i*getdy(points)/iterations)), (int)(points[0][1]+(i*getdx(points)/iterations)), (int)(points[1][1]+(i*getdy(points)/iterations)));
            }
            for(int i = 0; i < (mapWidth/unit); i++)
            {
                if(i == (mapWidth/unit)/2)
                {
                    g.setColor(Color.BLUE);//x axis
                    g.drawLine((int)(points[0][1] + i*(getOtherdx()/iterations)), (int)(points[1][1]+(i*getOtherdy()/iterations)),(int)(points[0][2] + i*(getOtherdx()/iterations)), (int)(points[1][2]+(i*getOtherdy()/iterations)));
                    g.fillOval((int)(points[0][2] + i*(getOtherdx()/iterations))-10, (int)(points[1][2]+(i*getOtherdy()/iterations))-10, 20,  20);
                }else{
                    g.setColor(Color.BLACK);
                    g.drawLine((int)(points[0][1] + i*(getOtherdx()/iterations)), (int)(points[1][1]+(i*getOtherdy()/iterations)),(int)(points[0][2] + i*(getOtherdx()/iterations)), (int)(points[1][2]+(i*getOtherdy()/iterations)));
                }
            }
        }
    }
    /* Poorly named and (I think) only used
    within the context of having to draw
    lines on the map */
    private double getdx(int[][] points){return points[0][3]-points[0][0];}
    private double getdy(int[][] points){return points[1][3] - points[1][0];}
    private double getOtherdy(){return mapPoints[1][0]-mapPoints[1][1];}
    private double getOtherdx(){return mapPoints[0][0]-mapPoints[0][1];}

    /*gives the current quadrant that the world's spin is in, and is
    used to calculate things like draw order and apply negative/positive
    x and y modifications to variables.*/
    public static int spinQuadrant()
    {
        if((int)(radSpin/(Math.PI/2.0)) + 1 <= 4)
        {
            return (int)(radSpin/(Math.PI/2.0)) + 1;
        }
        return 4;
    }
    private void drawRotationLine(Graphics g)//draws the line of rotation
    {
        g.setColor(Color.GREEN);
        g.drawLine((int)worldX,(int)worldY,(int)worldX+(int)(mapRadius*Math.sin(spinCalc)),(int)worldY+(int)(shrink(rotation)*(mapRadius*Math.cos(spinCalc))));
    }

    /* returns an array of ints where first index determines the variable
    ([0][i] = x values, [1][i] = y values) and returns the array to draw
    the upper portion of the map.*/
    public static int[][] mapTopPoints(double spinIn, int radiusIn)
    {
        int[][] points = new int[2][4];
        for(int variable = 0; variable < 2; variable++)
        {
            for(int i = 0; i < 4; i++)
            {
                switch(variable + 1)
                {
                    case 1:
                        points[variable][i]=(int)((radiusIn * Math.sin(spinIn + (i*(Math.PI/2)))));
                        break;
                    case 2:
                        points[variable][i]=(int)((radiusIn * Math.cos(spinIn + (i*(Math.PI/2)))));
                        break;
                }
            }
        }
        return points;
    }

    /*returns a constant that length is modified by for a given point since
    turning the field to make it flatter causes it to distort -- this is achieved
    by multiplying the value by a floating point number < 1*/
    public static double shrink(double rotationIn)
    {
        return Math.cos(rotationIn);
    }

    /*takes the rotation of the field and a height integer as parameters and returns the height
    of that object as viewed through the screen from the front -- meaning how tall it should appear
    to look as if it were manipulated in three dimensional space.*/
    public static double distortedHeight(double rotationIn, int heightIn)//one of the distortedHeights is redundant...
    {
        return Math.sin(rotationIn)*heightIn;
    }

    /*Updated every time paintComponent() is called. Handles primarily positioning and
    dimensions of the world, and starts threads when necessary for objects such as tiles.*/
    private void tick()
    {

        if(scale < 6.0 && MouseInput.dScale > 0)
        {
            scale += MouseInput.dScale;
        }
        if(scale > .5 && MouseInput.dScale < 0)
        {
            scale += MouseInput.dScale;
        }
        //scale = 10.0;
        unit = (int)(baseUnit * scale);
        straightUnit = (double)unit/Math.sqrt(2);
        mapWidth = (int)(baseMapWidth * scale);
        mapRadius = (int)(baseMapRadius*scale);
        mapHeight = (int)(baseMapHeight * scale);
        mapThickness = (int)(baseMapThickness * scale);
        requestFocus();
        MouseInput.updatePos();//updates the mouse's position.
        getShrink = shrink(rotation);//static getShrink is used so that other classes can get it easily.
        mapPoints = mapTopPoints(spin, mapRadius);//more efficient to have an instance variable that updates position rather than having to calculated it every time it is called.

        for(int i = 0; i < 4; i++)//places the map in relation to its position, as the method that gets its array only gives its position compared to nothing else. May be a little slower to do them separately, but shouldn't really matter much.
        {
            mapPoints[0][i] = (int)worldX + mapTopPoints(spin, mapRadius)[0][i];
            mapPoints[1][i] = (int)worldY+(int)(mapTopPoints(spin, mapRadius)[1][i] * shrink(rotation));
        }
        if(!MouseInput.clicked)
        {
            worldX+= Input.givedx;worldY+= Input.givedy;
        }else{
            worldX = (MouseInput.tempWorldX - (MouseInput.dragdx));
            worldY = (MouseInput.tempWorldY - (MouseInput.dragdy));
        }
        spin += Input.dSpin;
        spinCalc += Input.dSpin;//spinCalc can spin on indefinitely. Could add another if/else if clause along with rotation and radspin.
        radSpin += Input.dSpin;
        rotation+=Input.dRotation;
        /*resets the spins if they go over or under a full revolution*/

        if(rotation > Math.PI/2.3){
            rotation = Math.PI/2.3;
        }else if(rotation<0.5){
            rotation = .5;
        }if(radSpin > (2*Math.PI)){
            radSpin -= 2*Math.PI;
        }else if(radSpin < 0){
            radSpin += 2*Math.PI;
        }
        if(tempQuadrant != spinQuadrant() || MouseInput.clickJustReleased() || MouseInput.clicked || LevelLoader.sortTiles || Tile.resortTiles)//needs to run last
        {
            //Thread t = new Thread(ts);
            //ts.setThread(t);
            //t.start();
            td2.getThread().interrupt();
            td2.setThread(new Thread(td2));
            td2.getThread().start();
            //td2.run();

            tempQuadrant = spinQuadrant();

            //ts.getThread().interrupt();
            //ts.setThread(new Thread(ts));
            //ts.getThread().start();
            LevelLoader.sortTiles = false;
        }

        for(int i = 0; i < TileSorter.tileList.size(); i++)
        {
            try{
                ts.getThread().join();//waits for editing to be finished first. Maybe there is a better way to do this? Seems like it isn't as fast as possible this way.
            }catch(Exception e){}//do i want to throw anything here?

            TileSorter.tileList.get(i).getThread().interrupt();
            Thread t = new Thread(TileSorter.tileList.get(i));
            t.start();
            TileSorter.tileList.get(i).setThread(t);//shouldn't be working with spinTile but does?
        }
        //if(Input.givedx != 0 || Input.givedy != 0 || Input.dSpin != 0 || Input.dRotation != 0)//used to fire threads that only need to update when the map moves.
        //{
            for(int i = 0; i < TileSorter.tileList.size(); i++)
            {
                for(int j = 0; j < TileSorter.tileList.get(i).getSceneryList().size(); j++)
                {
                    TileSorter.tileList.get(i).getSceneryList().get(j).getThread().interrupt();
                    TileSorter.tileList.get(i).getSceneryList().get(j).setThread(new Thread(TileSorter.tileList.get(i).getSceneryList().get(j)));
                    TileSorter.tileList.get(i).getSceneryList().get(j).getThread().start();
                }
            }
        //}
        player.getThread().interrupt();
        player.setThread(new Thread(player));
        player.getThread().start();

        /*synchronized(loopNotify)
        {
            loopNotify.notify();
        }*/
        //System.out.println(TileDrawer2.tileList.size());
    }

    public void setGameVisible(boolean b)
    {
        volumeSlider.setVisible(b);
        turnLeft.setVisible(b);
        turnRight.setVisible(b);
        resetLevel.setVisible(b);
    }

    /*What happens when the random shapes button is clicked.*/
    @Override
    public void actionPerformed(ActionEvent e)
    {
        String command = e.getActionCommand();
        if(command.equals("tick"))
        {
            tick();
        }else if(command.equals("randomShapes"))
        {

            baseMapWidth = 525;
            baseMapHeight = 525;
            baseUnit = 37;
            baseStraightUnit = (double)baseUnit/Math.sqrt(2);
            baseMapRadius = baseMapWidth/2;
            squareWidth = (double)mapWidth/Math.sqrt(2);
            squareRadius = (double)baseMapRadius/Math.sqrt(2);

            unit = (int)(baseUnit * scale);
            straightUnit = (double)unit/Math.sqrt(2);
            mapWidth = (int)(baseMapWidth * scale);
            mapRadius = (int)(baseMapRadius*scale);
            mapHeight = (int)(baseMapHeight * scale);
            mapThickness = (int)(baseMapThickness * scale);
            //td.populateBoardFixedProportions(2,2,10);
        }else if(command.equals("turnLeft"))
        {
            spin += Math.PI/2.0;
            radSpin += Math.PI/2.0;
            spinCalc += Math.PI/2.0;
        }else if(command.equals("turnRight"))
        {
            spin -= Math.PI/2.0;
            radSpin -= Math.PI/2.0;
            spinCalc -= Math.PI/2.0;
        }else if(command.equals("resetLevel"))
        {

            LevelLoader ll = new LevelLoader(player, this);
            ll.spawnLevel(UI.level);
            MouseInput.scrollType = "Zoom";

        }
    }

    public static int getSortSlope()
    {
        int quad = spinQuadrant();
        if(quad == 1 || quad == 3)
        {
            return -1;
        }else{
            return 1;
        }
    }

    public static int getBottomCornerConstant()
    {
        int quad = spinQuadrant();
        if(quad == 1 || quad == 4)
        {
            return -worldTilesHeight/2;
        }else{
            return worldTilesHeight/2;
        }
    }

    @Override
    public void run()
    {

        //tick();

    }

    @Override
    public void stateChanged(ChangeEvent e)
    {
        JSlider numIn = (JSlider)e.getSource();

        a.setVolume((float)numIn.getValue());
    }

}


text:
sudo ip link set dev vsff1-sf11 down
sudo ip link del dev vsff1-sf11
sudo ip link set dev vsf11-sff1 down
sudo ip link del dev vsf11-sff1
sudo ip link add vsff1-sf11 type veth peer name vsf11-sff1
sudo ip link set dev vsff1-sf11 address f6:00:00:ff:01:01
sudo ip link set dev vsf11-sff1 address f6:00:00:0f:11:01
sudo ip link set dev vsff1-sf11 up
sudo ip link set dev vsf11-sff1 up
sudo ovs-vsctl -- \
    --if-exists del-port sff1 vsff1-sf11 -- \
    --if-exists del-br sff1
sudo ovs-vsctl add-br sff1 -- set bridge sff1 other_config:hwaddr=f6:00:00:ff:01:00 -- \
    set bridge sff1 other-config:disable-in-band=true
sudo ovs-vsctl add-port sff1 vsff1-sf11 -- set Interface vsff1-sf11 ofport_request=1

sudo ovs-vsctl -- \
    --if-exists del-port sf11 vsf11-sff1 -- \
    --if-exists del-br sf11
sudo ovs-vsctl add-br sf11 -- set bridge sf11 other_config:hwaddr=f6:00:00:0f:11:00 -- \
    set bridge sf11 other-config:disable-in-band=true
sudo ovs-vsctl add-port sf11 vsf11-sff1 -- set Interface vsf11-sff1 ofport_request=1
sudo ovs-ofctl del-flows sf11
sudo ovs-ofctl add-flow sf11 priority=10,actions=
sudo ovs-ofctl add-flow sf11 priority=100,in_port=1,tcp,tp_dst=80,actions=output:in_port

# add sf12
sudo ip link set dev vsff1-sf12 down
sudo ip link del dev vsff1-sf12
sudo ip link set dev vsf12-sff1 down
sudo ip link del dev vsf12-sff1
sudo ip link add vsff1-sf12 type veth peer name vsf12-sff1
sudo ip link set dev vsff1-sf12 address f6:00:00:ff:01:02
sudo ip link set dev vsf12-sff1 address f6:00:00:0f:12:01
sudo ip link set dev vsff1-sf12 up
sudo ip link set dev vsf12-sff1 up
sudo ovs-vsctl --if-exists del-port sff1 vsff1-sf12
sudo ovs-vsctl --may-exist add-br sff1
sudo ovs-vsctl add-port sff1 vsff1-sf12 -- set Interface vsff1-sf12 ofport_request=2

sudo ovs-vsctl -- \
    --if-exists del-port sf12 vsf12-sff1 -- \
    --if-exists del-br sf12
sudo ovs-vsctl add-br sf12 -- set bridge sf12 other_config:hwaddr=f6:00:00:0f:12:00
sudo ovs-vsctl add-port sf12 vsf12-sff1 -- set Interface vsf12-sff1 ofport_request=1
sudo ovs-ofctl del-flows sf12
sudo ovs-ofctl add-flow sf12 priority=10,actions=
sudo ovs-ofctl add-flow sf12 priority=100,in_port=1,tcp,tp_dst=80,actions=output:in_port

sudo ovs-vsctl add-port sff1 ws6 -- set Interface ws6 type=internal \
    -- set Interface ws6 mac="f6\:00\:00\:ff\:01\:06" \
    -- set Interface ws6 ofport_request=6
sudo ip netns add ws6
sudo ip link set ws6 netns ws6
sudo ip netns exec ws6 ip addr add dev ws6 10.1.6.1/24
sudo ip netns exec ws6 ip link set dev lo up
sudo ip netns exec ws6 ip link set dev ws6 up
sudo ip netns exec ws6 ip route add default via 10.1.6.1
sudo ip route add 10.1.6.0/24 dev sff1

wget -O - http://10.1.6.1:80

redpajama_set_name: RedPajamaGithub


text:
<TITLE>Review for Empire of the Sun (1987)</TITLE>
<LINK REL="STYLESHEET" TYPE="text/css" HREF="/ramr.css">

Empire of the Sun (1987)

reviewed by
William Tsun-Yuk Hsu

                            EMPIRE OF THE SUN
                    Comments by William Tsun-Yuk Hsu
                   Copyright 1987 William Tsun-Yuk Hsu

     Much has been said in this newsgroup about Steven Spielberg and  EMPIRE OF
THE SUN, the film his admirers point to as his masterpiece.  I was not a
Spielberg hater before I saw EMPIRE OF THE SUN (but then I had not seen a
Spielberg movie since E.T., when I was a much more naive movie watcher.)  I
came out of EMPIRE OF THE SUN really detesting Spielberg's idiosyncracies and
excesses.

     I'll only touch on the essentials.  As usual I'll try to steer clear of
politics ("It's a travesty of the word ideologue to call Spielberg one."--
John R.)  I won't make any comparisons with the book, as I have not read it
(though I'm familiar with Ballard's earlier work, which I've been told is quite
different from EMPIRE OF THE SUN).

     There are several scenes in EMPIRE OF THE SUN that I really liked.  The
crowd scenes in the beginning were very effective.  The scene in the junk yard
with the furniture and piano was brilliant.

     But as a whole, EMPIRE OF THE SUN is a small-minded, blatantly
manipulative movie.  It drips with sentimentality and stock Spielberg/Hollywood
images and situations, and clumsily tramples over its interesting moments with
contrived histrionics.  Several scenes have effective sound devices, but the
movie drowns under a sea of saccharine strings and "transcendental" female
choral music.

     The beginning of the scene with the kamikaze pilots was handled skillfully,
but Spielberg the arch-audience-manipulator takes over when the kid (Jim)
salutes them and starts singing.  Not only does he sing, but the song echoes
through the POW camp, and by the time it becomes a female vocalist I suppose
we're all supposed to be crying.  (And of course Jim has to look like an E.T.
kid, and have a Vienna Boys Choir-type voice.  But that's a matter of taste.)

     Spielberg even sabotages his own clumsy attempt at structure near the end.
Jim is riding his bicycle in the abandoned camp (obvious reflection of an
earlier scene where he was riding his bicycle in an abandoned house.)  Of
course Spielberg cannot resist another typically Spielberg-esque miracle when a
canister of food falls through the roof, and we are treated to the typical
Hollywood radiant "sense of wonder" shot of Jim's face.

     Finally, there is no excuse for this movie to last 2-1/2 hours.  Much of
what happened in the last hour were non-essential action sequences or overlong,
rapt contemplations of not very interesting images.

     Obviously Spielberg is not an inept film maker.  Some scenes in EMPIRE OF
THE SUN are really effective (recall, for example, the scene where Jim tries to
stop his former servants from plundering his house, and one of them
nonchalantly walks over and slaps him).  But it seems Spielberg will never pass
up on the smallest opportunity to tweak at the collective heartstrings of his
audience.  And he doesn't seem willing to break free of the Hollywood
vocabulary of stock images and characters (some of which he has created, it is
true).  Only the memory of several well-executed scenes kept me from walking
out on this movie.

Bill

The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).

The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.

Please direct comments/criticisms of the review to relevant newsgroups.

Broken URLs inthe reviews are the responsibility of the author.

The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.

Related links: index of all rec.arts.movies.reviews reviews


text:
rf.StandaloneDashboard(function(db){
	var chart = new ChartComponent();
	chart.setDimensions (4, 4);
	chart.setCaption("First Chart");
	chart.setLabels (["Jan", "Feb", "Mar"]);
	chart.addSeries ("beverages", "Beverages", [1355, 1916, 1150]);
	chart.addSeries ("packaged_foods", "Packaged Foods", [1513, 976, 1321]);
	db.addComponent (chart);

	var chart2 = new ChartComponent();
	chart2.setDimensions (4, 4);
	chart2.setCaption("Second Chart");
	chart2.setLabels (["A", "B", "C"]);
	chart2.addSeries("series_1", "Series 1", [1, 2, 3]);
	db.addComponent (chart2);

	chart.onItemClick (function (params) {
		chart2.updateSeries ("series_1", [3, 5, 2]);
	});
});


text:
namespace Gu.Wpf.FlipView
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows;
    using System.Windows.Automation.Peers;
    using Gu.Wpf.FlipView.Internals;

    /// <summary>
    /// An <see cref="AutomationPeer"/> for <see cref="FlipView"/>.
    /// </summary>
    public class FlipViewAutomationPeer : SelectorAutomationPeer
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="FlipViewAutomationPeer"/> class.
        /// </summary>
        /// <param name="owner">The <see cref="FlipView" /> that is associated with this <see cref="FlipViewAutomationPeer" />.</param>
        public FlipViewAutomationPeer(FlipView owner)
            : base(owner)
        {
        }

        /// <inheritdoc />
        protected override ItemAutomationPeer? CreateItemAutomationPeer(object item) => null;

        /// <inheritdoc />
        protected override List<AutomationPeer> GetChildrenCore()
        {
#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type.
            return this.Owner.VisualChildrenRecursive()
                       .Select(CreatePeerForElement)
                       .Where(x => x != null)
                       .ToList();
#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type.

            static AutomationPeer? CreatePeerForElement(DependencyObject o)
            {
                return o switch
                {
                    UIElement uiElement => UIElementAutomationPeer.CreatePeerForElement(uiElement),
                    UIElement3D uiElement3D => UIElement3DAutomationPeer.CreatePeerForElement(uiElement3D),
                    _ => null,
                };
            }
        }

        /// <inheritdoc />
        protected override string GetClassNameCore() => "FlipView";
    }
}


text:
package src.components;

import com.artemis.Component;

/**
 * User: Eptwalabha
 * Date: 08/02/14
 * Time: 15:45
 */
public class Coin extends Component {

    private int coinValue;

    public Coin(int value) {
        coinValue = value;
    }

    public int getCoinValue() {
        return coinValue;
    }

    public void setCoinValue(int coinValue) {
        this.coinValue = coinValue;
    }
}


text:
package com.ctrip.platform.dal.dao;

/**
 * @author c7ch23en
 */
public interface PojoExecutionResult extends ExecutionResult<Integer> {

    int getPojoIndex();

}


text:
'use strict';

const stampit = require('stampit');
const j5 = require('johnny-five');
const Board = j5.Board;
const _ = require('lodash');
const Promise = require('bluebird');
const j5Classes = require('./j5-reflect');
const Joi = require('joi');

const Adapter = stampit({
  refs: {
    debug: false,
    repl: false,
    components: {}
  },
  props: {
    j5Classes: j5Classes
  },
  init(context) {
    const seneca = this.seneca = context.args.shift();
    const done = context.args.shift();

    const stamp = context.stamp;
    const boardOpts = _.omit(this, _(stamp.fixed.props)
      .keys()
      .concat(_.keys(stamp.fixed.methods))
      .concat('seneca', 'components')
      .value());

    return new Promise((resolve, reject) => {
      seneca.log.debug(boardOpts);
      this.board = new Board(boardOpts)
        .on('ready', resolve)
        .on('error', reject);
    })
      .return(this)
      .nodeify(done);
  },
  methods: {
    component(klass, opts, done) {
      return Promise.try(() => {
        Joi.assert(klass, Joi.string().required());
        if (!this.j5Classes[klass]) {
          throw new Error(`Unknown class ${klass}`);
        }
        Joi.assert(opts, Joi.object());
        Joi.assert(done, Joi.func());

        opts = opts || {};
        opts.id = opts.id || _.uniqueId(`${klass}-`);

        this.components[opts.id] = new j5[klass](opts);

        return _.extend({
          id: opts.id
        }, this.j5Classes[klass]);
      })
      .nodeify(done);
    }
  }
});

module.exports = Adapter;


text:
require 'active_model'
require 'golden_fleece/validations/validator_context'

module GoldenFleece
  module Validations
    module ActiveModel
      class FleeceSchemaConformanceValidator < ::ActiveModel::EachValidator
        def validate_each(record, attribute, persisted_json)
          context = record.class.fleece_context
          errors = ValidatorContext.new(record, attribute, persisted_json, context.schemas[attribute], '/').validate

          errors.each { |e| record.errors.add attribute, e }
          errors.empty?
        end
      end
    end
  end
end


text:
#ifndef MEMORY_HPP
#define MEMORY_HPP

#include <cstdint>

class Memory
{
public:
    Memory();
    Memory(unsigned maxSize);
    virtual ~Memory();

    uint8_t GetByte(unsigned pos) const;
    uint16_t GetWord(unsigned pos) const;

    void SetByte(unsigned pos, uint8_t byte);
    void SetWord(unsigned pos, uint16_t word);

    unsigned GetSize() const;
    void Reset();
    void Insert(unsigned pos, const uint8_t * array, unsigned size);
    uint8_t *GetPart(unsigned pos, uint8_t *buffer, unsigned buff_size);
private:
    Memory(const Memory&);
    uint8_t *memory;
    uint8_t *endIter;
    unsigned size;
};

#endif /* MEMORY_HPP */


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Azure.Identity
{
    internal class ClientAssertionCredentialOptions : TokenCredentialOptions
    {
        internal CredentialPipeline Pipeline { get; set; }

        internal MsalConfidentialClient MsalClient { get; set; }
    }
}


text:
'use strict';

const cronious = require('cronious');
const FetchToMongoTask = require('./fetchToMongoTask');

/**
 * @param {{
     *    sourceUrl: (string|string[]|function (): Promise.<string[]>|function (): Promise.<string>)
     *    collection: mongodb.Collection
     *    taskId?: string
     *    lifetime?: number,
     * }} taskOptions
 * @returns {Promise.<Function>}
 */
module.exports = function (taskOptions) {

    const runner = new cronious.Runner({
        collection: taskOptions.collection,
        checkInterval: 10 * 1000
    });

    const task = new FetchToMongoTask(taskOptions);

    return runner.registerTask(task).then(() => {

        runner.startTriggeringTasks();

        return {
            stopFetchToMongoTask: () => runner.stopTriggeringTasks()
        };
    });
};


text: export PATH=$PATH:/usr/local/go/bin


text:
//
//  SiteListTable.m
//  Victron Energy
//
//  Created by Thijs on 3/12/13.
//  Copyright (c) 2013 Thijs Bouma. All rights reserved.
//

#import "SiteListTableViewController.h"
#import "SitesOKCell.h"
#import "SitesWithAlarmCell.h"
#import "SitesOutDatedCell.h"
#import "Tools.h"
#import "SiteInfo.h"
#import "Data.h"
#import <QuartzCore/QuartzCore.h>
#import "SVProgressHUD.h"
#import "SiteDetailViewController.h"
#import "SitesScrollViewController.h"
#import "AttributesInfo.h"
#import "KeychainItemWrapper.h"
#import "SVWebViewController.h"
#import "LoginViewController.h"
#import "NoSitesAvailableCell.h"
#import "M2MAboutViewController.h"
#import "M2MLoginService.h"
#import "M2MCredentials.h"
#import "M2MCredentialsStorage.h"
#import "M2MSiteService.h"
#import "M2MAttributesService.h"

const float kSearchBarHeight = 44.0f;

@implementation SiteListTableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
    // Set the screen name on the tracker so that it is used in all hits sent from this screen.
    [tracker set:kGAIScreenName value:@"SiteList"];

    // Send a screenview.
    [tracker send:[[GAIDictionaryBuilder createAppView]  build]];

    self.sitesAlarmsCount = 0;
    self.sitesOkCount = 0;
    self.sitesOldCount = 0;
    self.sitesAlarmsArray = [[NSMutableArray alloc]init];
    self.sitesOkArray = [[NSMutableArray alloc]init];
    self.sitesOldArray = [[NSMutableArray alloc]init];

    self.sitesList = [NSMutableArray new];
    self.sitesListResults = [NSMutableArray new];

    self.selectedSite = nil;
    self.isShowingSearchResults = NO;

    self.tableView.separatorColor = [UIColor clearColor];
    self.tableView.backgroundColor = COLOR_BACKGROUND;

    self.sitesSearchBar.placeholder = NSLocalizedString(@"searchbar_placeholdertext", @"searchbar_placeholdertext");
    self.sitesSearchBar.backgroundImage = [UIImage imageNamed:@"bar_search_background.png"];

    [self.tableView setSeparatorColor:[UIColor clearColor]];

    UIImage *clearText = [UIImage imageNamed:@"button_exitsearch.png"];
    [self.sitesSearchBar setImage:clearText forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];

    UIImage *searchIcon = [UIImage imageNamed:@"icon_search.png"];
    [self.sitesSearchBar setImage:searchIcon forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];

    for (SiteListTableViewController *searchBarSubview in [_sitesSearchBar subviews]) {

        if ([searchBarSubview conformsToProtocol:@protocol(UITextInputTraits)]) {

            @try {
                [(UITextField *)searchBarSubview setReturnKeyType:UIReturnKeyDone];
                [(UITextField *)searchBarSubview setEnablesReturnKeyAutomatically:NO];
            }
            @catch (NSException * e) {

            }
        }
    }

    if (_refreshHeaderView == nil) {

		EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc]
                                           initWithFrame:CGRectMake(0.0f,
                                                                0.0f - self.tableView.bounds.size.height,
                                                                    self.view.frame.size.width,
                                                                    self.tableView.bounds.size.height)];
		view.delegate = self;
		[self.tableView addSubview:view];
		_refreshHeaderView = view;
	}

    self.navigationItem.backBarButtonItem.title = NSLocalizedString(@"back_button_title", @"back_button_title");
    self.navigationItem.title = NSLocalizedString(@"site_summary_title", @"site_summary_title");

    self.aboutButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.aboutButton setImage:[UIImage imageNamed:@"ic_about_default"] forState:UIControlStateNormal];
    self.aboutButton.frame = CGRectMake(0.0, 0.0, [UIImage imageNamed:@"ic_about_default"].size.width, [UIImage imageNamed:@"ic_about_default"].size.height);
    [self.aboutButton addTarget:self action:@selector(aboutButtonPressed:) forControlEvents:UIControlEventTouchUpInside];

    self.webviewButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.webviewButton setImage:[UIImage imageNamed:@"ic_menu_web.png"] forState:UIControlStateNormal];
    self.webviewButton.frame = CGRectMake(0.0, 0.0, [UIImage imageNamed:@"ic_menu_web.png"].size.width, [UIImage imageNamed:@"ic_menu_web.png"].size.height);
    [self.webviewButton addTarget:self action:@selector(webViewButtonPressed:) forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem *rightButtonWebview = [[UIBarButtonItem alloc] initWithCustomView:self.webviewButton];
    UIBarButtonItem *rightButtonAbout = [[UIBarButtonItem alloc] initWithCustomView:self.aboutButton];

    self.navigationItem.rightBarButtonItems = @[rightButtonWebview,rightButtonAbout];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationActive:)
                                                 name:UIApplicationDidBecomeActiveNotification object:nil];
}

- (void)applicationActive:(id)applicationActive
{
    if([self.sitesList count] != 0){
        self.lastReloadDate = nil;
        [self reloadIfNeeded];
    }

}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self scrollSiteListToSite:self.indexOfSelectedSiteInList withDuration:0.0f];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    M2MLoginService *loginService = [M2MLoginService sharedInstance];
    if(!loginService.loggedIn) {

        M2MCredentialsStorage *credentialsStorage = [M2MCredentialsStorage new];
        M2MCredentials *credentials = [credentialsStorage getCurrentUserCredentials];

        if([credentials.username isEqualToString:@""] || [credentials.username isEqualToString:LOGIN_DEMO_EMAIL]){
            [self performSegueWithIdentifier:@"loginSegue" sender:self];
            return;
        }

        [SVProgressHUD show];
        [loginService loginWithCredentials:credentials success:^(NSInteger statusCode) {
            [SVProgressHUD dismiss];
            [self reloadIfNeeded];
        } failure:^(NSInteger statusCode) {
            [SVProgressHUD dismiss];
            [self performSegueWithIdentifier:@"loginSegue" sender:self];
        }];
    }else{
        [self reloadTableViewDataSource];
    }
}

- (void)reloadIfNeeded
{
    NSDate *currentDate = [NSDate date];
    if(!self.lastReloadDate){
        self.lastReloadDate = currentDate;
        [self reloadTableViewDataSource];
        return;
    }

    NSTimeInterval secondsElapsed = [currentDate timeIntervalSinceDate:self.lastReloadDate];
    CGFloat minutesElapsed = secondsElapsed / 60;

    if(minutesElapsed > 5){
        [self reloadTableViewDataSource];
        self.lastReloadDate = currentDate;
    }
}

/** iPad - get a reference to the Splitview's detail view manager */
- (SitesScrollViewController *)detailViewManager
{
    if (_detailViewManager) {
        return _detailViewManager;
    }
    _detailViewManager = (SitesScrollViewController *)[[self.splitViewController.viewControllers lastObject]topViewController];
    return _detailViewManager;
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // iPad - If the user has just logged in, select the first site and show its detail view.
    if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) &&
        (!self.selectedSite) &&
        [indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row &&
        !self.isShowingSearchResults) {
        // End of loading table view means we have site info to select.
        [self loadFirstSiteDetailView];
        // Having the number of sites we can resize the scrollview for the number of required views.
        [self.detailViewManager resizeScrollView];
    }
}

/** iPad - Tells the detail view manager to shows the detail view of the first site in the list.
 * NOTE: we do this without invoking tableview:didSelectRowAtIndexPath: to prevent polluting Google Analytics. */
- (void)loadFirstSiteDetailView
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && self.indexPathSite && ([self.sitesList count] > 0)) {

        // Send relevant Site Info to the detail view manager.
        self.detailViewManager.selectedSite = [self.sitesListResults objectAtIndex:self.indexPathSite.row];
        self.detailViewManager.siteIndex = self.indexPathSite.row;
        self.detailViewManager.sitesList = self.sitesListResults;

        // Tell the detail view manager to load the selected detail view controller.
        [self.detailViewManager loadSelectedView];
    }
}

- (NSIndexPath *)getIndexPathForSelectedSite:(int)sitePositionInSiteDetails{
    NSIndexPath *indexPathSite;

    if ([self.tableView numberOfRowsInSection:0] > sitePositionInSiteDetails) {
        indexPathSite = [NSIndexPath indexPathForRow:sitePositionInSiteDetails
                                           inSection:0];
    } else if (([self.tableView numberOfRowsInSection:0] + [self.tableView numberOfRowsInSection:1]) > sitePositionInSiteDetails) {
        indexPathSite = [NSIndexPath indexPathForRow:(sitePositionInSiteDetails - [self.tableView numberOfRowsInSection:0])
                                           inSection:1];
    } else if (([self.tableView numberOfRowsInSection:0] + [self.tableView numberOfRowsInSection:1] + [self.tableView numberOfRowsInSection:2]) > sitePositionInSiteDetails) {
        indexPathSite = [NSIndexPath indexPathForRow:(sitePositionInSiteDetails - [self.tableView numberOfRowsInSection:0] - [self.tableView numberOfRowsInSection:1])
                                           inSection:2];
    }

    return indexPathSite;
}

- (void)scrollSiteListToSite:(int)sitePositionInSiteDetails withDuration:(float)duration
{
    self.indexPathSite = [self getIndexPathForSelectedSite:sitePositionInSiteDetails];

    // We use this animateWithDuration because then we have a smooth scrolling, if we use scrollToRowAtIndexPath:animated:YES it stammers
    [UIView animateWithDuration: duration
                     animations: ^{
                         [self.tableView scrollToRowAtIndexPath:self.indexPathSite atScrollPosition:UITableViewScrollPositionNone animated:NO];
                     }completion: ^(BOOL finished){
                         // After we scrolled to the row we selected it
                         [self.tableView selectRowAtIndexPath:self.indexPathSite
                                                     animated:NO
                                               scrollPosition:UITableViewScrollPositionNone];
                     }
     ];
}

- (IBAction)logOutButtonPressed:(id)sender {
    M2MCredentialsStorage *credentialsStorage = [M2MCredentialsStorage new];
    M2MCredentials *credentials = [credentialsStorage getCurrentUserCredentials];

    NSString *logoutMessage = [NSString stringWithFormat:NSLocalizedString(@"log_out_button", @"log_out_button"),credentials.username];

    UIAlertView *message = [[UIAlertView alloc] initWithTitle:nil
                                                      message:logoutMessage
                                                     delegate:self
                                            cancelButtonTitle:@"No"
                                            otherButtonTitles:@"Yes", nil];
    [message show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];

        [tracker send:[[GAIDictionaryBuilder createEventWithCategory:GA_EVENT_CATEGORY_ACTION
                                                              action:GA_WITH_ACTION_BUTTON_PRESS
                                                               label:@"logout_button"
                                                               value:nil] build]];

        ((AppDelegate *)[[UIApplication sharedApplication] delegate]).userToken = @"";

        M2MLoginService *loginService = [M2MLoginService sharedInstance];
        [loginService logout];

        UIViewController *presentingVC;
        // Determine if we should present the modal login screen from our self (iPhone) or the SplitViewController (iPad)
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
            presentingVC = self;
        } else {
            presentingVC = self.splitViewController;
            // iPad - If we are in portrait we will hide the master view popover before we present the login screen,
            // so that on dismissal of the login view the master popover will slide in.
            [self.detailViewManager hideMasterPopoverInPortrait];
        }

        // We want to show the login screen *animated*, so instead of simply using performSegueWithIdentifier:: we do the following:
        LoginViewController *vc =  (LoginViewController*)[self.storyboard instantiateViewControllerWithIdentifier:@"LoginViewNavigationController"];
        [vc setModalPresentationStyle:UIModalPresentationFullScreen];

        [presentingVC presentViewController:vc animated:YES completion:^(void){
            // Reload the site list without any sites, so that on dismissal of the login view the previous site data is not briefly visible.
            self.sitesAlarmsCount = 0;
            self.sitesOkCount     = 0;
            self.sitesOldCount    = 0;
            [self.sitesAlarmsArray removeAllObjects];
            [self.sitesOkArray     removeAllObjects];
            [self.sitesOldArray    removeAllObjects];
            [self.sitesList        removeAllObjects];
            [self.sitesListResults removeAllObjects];
            self.selectedSite = nil;
            self.lastReloadDate = nil;

            [self.tableView reloadData];

            // Reset the detail view manager - remove all loaded site details.
            for (SiteDetailViewController *vc in self.detailViewManager.viewControllerArray) {
                if (![vc isEqual:[NSNull null]]) {
                    [vc removeFromParentViewController];
                    [vc.view removeFromSuperview];
                }
            }
            [self.detailViewManager.viewControllerArray removeAllObjects];
            self.detailViewManager.siteIndex   = -1;
            self.detailViewManager.currentPage = -1;
            self.detailViewManager.sitesList = nil;
            self.detailViewManager.selectedSite = nil;

            self.indexPathSite = nil;

            // Close the Historic Data or Webview screen, if open.
            [self.detailViewManager.navigationController popToRootViewControllerAnimated:NO];
        }];
    }
}

-(void)aboutButtonPressed:(id)sender {

    M2MAboutViewController *aboutViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"aboutNavBar"];

    [self.navigationController presentViewController:aboutViewController animated:YES completion:nil];
}

- (void)webViewButtonPressed:(id)sender {

    M2MCredentialsStorage *credentialsStorage = [M2MCredentialsStorage new];
    M2MCredentials *credentials = [credentialsStorage getCurrentUserCredentials];

    NSString *username = credentials.username;
    NSString *password = credentials.password;

    SVWebViewController *webViewController = [[SVWebViewController alloc] init];
    webViewController.title = NSLocalizedString(@"website_title", @"website_title");

    NSLog(@"Site list table contr");

    [(AppDelegate *)[[UIApplication sharedApplication] delegate] getToken:username password:password web:webViewController redirect:@"/" controller:self site:0];

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        [self.navigationController pushViewController:webViewController animated:YES];
    } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        UINavigationController *modalNavigationController = [[UINavigationController alloc] initWithRootViewController:webViewController];
        modalNavigationController.navigationBar.translucent = NO;
        NSString *backButton = NSLocalizedString(@"back_button_webview", @"back_button_webview");
        webViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:backButton style:UIBarButtonItemStylePlain target:self action:@selector(backFromWebview)];
        [self presentViewController:modalNavigationController animated:YES completion:nil];
    }

    id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];

    [tracker send:[[GAIDictionaryBuilder createEventWithCategory:GA_EVENT_CATEGORY_ACTION
                                                          action:GA_WITH_ACTION_BUTTON_PRESS
                                                           label:@"settings_website_button"
                                                           value:nil] build]];
}

- (void)backFromWebview
{
    NSLog(@"Back from Webview SiteListTableView");
    ((AppDelegate *)[[UIApplication sharedApplication] delegate]).selectedSiteId = 0;
    self.selectedSite = nil;
    [self dismissViewControllerAnimated:YES completion:nil];
}

-(void)sortSitesForSiteListWithArray:(NSMutableArray *)sitesArray{

    NSMutableArray *sitesTempArray = [[NSMutableArray alloc]init];
    [self.sitesAlarmsArray removeAllObjects];
    [self.sitesOkArray removeAllObjects];
    [self.sitesOldArray removeAllObjects];

    for (SiteInfo *site in sitesArray) {
        // If the site data is old put the site in the old data list
        if (site.siteStatus == OLD ) {
            [self.sitesOldArray addObject:site];
        } else if (site.siteStatus == ALARMS) {
            [self.sitesAlarmsArray addObject:site];
        } else if (site.siteStatus == OK) {
            [self.sitesOkArray addObject:site];
        }
    }

    self.sitesAlarmsCount = [self.sitesAlarmsArray count];
    self.sitesOkCount = [self.sitesOkArray count];
    self.sitesOldCount = [self.sitesOldArray count];

    for (SiteInfo *site in self.sitesAlarmsArray) {
        [sitesTempArray addObject:site];
    }

    for (SiteInfo *site in self.sitesOkArray) {
        [sitesTempArray addObject:site];
    }

    for (SiteInfo *site in self.sitesOldArray) {
        [sitesTempArray addObject:site];
    }

    if (sitesArray == self.sitesList) {
        self.sitesList = sitesTempArray;
    }

    self.sitesListResults = sitesTempArray;

    if (![self.sitesListResults count]) {
        self.noSiteAvailable = YES;
    } else {
        self.noSiteAvailable = NO;
    }

    [self.tableView reloadData];
}

-(void)getSites
{
    __weak typeof(self)weakSelf = self;

    [[M2MSiteService new] getSitesWithSuccess:^(NSArray *sites) {
        weakSelf.sitesList = [sites mutableCopy];
        [weakSelf reloadTableViewWithData:nil];

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            weakSelf.detailViewManager.sitesList = weakSelf.sitesList;
        }

        if(weakSelf.scrollViewController){
            weakSelf.scrollViewController.sitesList = weakSelf.sitesList;
        }
    } failure:^(NSInteger statusCode) {
        NSLog(@"getSites SiteListTableViewController. Status: %ld", (long)statusCode);
        [M2MNetworkErrorHandler checkToShowAlertViewForResponseCode:statusCode];
    }];
}

-(void)reloadTableViewWithData:(NSNotification *)notification
{
    [self sortSitesForSiteListWithArray:self.sitesList];

    [self doneLoadingTableViewData];

    // iPad - Select and scroll to the appropriate Site.
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

        // On login, determine the indexPath of the first row of the first *visible* section.
        if (!self.selectedSite && [self.sitesList count]) {
            self.indexPathSite = [NSIndexPath indexPathForRow:0 inSection:0];
            if (!self.sitesAlarmsCount && self.sitesOkCount > 0) {
                self.indexPathSite = [NSIndexPath indexPathForRow:0 inSection:1];
            } else if (!self.sitesAlarmsCount && !self.sitesOkCount && self.sitesOldCount > 0) {
                self.indexPathSite = [NSIndexPath indexPathForRow:0 inSection:2];
            }
        }
        // Select and scroll to the Site.
        // If we have no sites and thus no indexPathSite, attempting scrollToRowAtIndexPath will crash.
        if (self.indexPathSite && [self.sitesList count]) {
            [self.tableView selectRowAtIndexPath:self.indexPathSite
                                        animated:NO
                                  scrollPosition:UITableViewScrollPositionNone];

            [self.tableView scrollToRowAtIndexPath:self.indexPathSite atScrollPosition:UITableViewScrollPositionNone animated:NO];
        }
    }

}

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    //Reload the table view on orientation change to make sure the layout is displayed correctly
    [self reloadTableViewDataSource];

    [self.sitesSearchBar resignFirstResponder];
}

#pragma mark -
#pragma mark Searchbar

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [self.sitesSearchBar resignFirstResponder];
}

- (void)searchBar:(UISearchBar *)aSearchbar textDidChange:(NSString *)searchText{

    self.sitesListResults = [self.sitesList copy];

    NSMutableArray* searchResults = [[NSMutableArray alloc] initWithArray:self.sitesListResults];
    //remove the items that do not match with the search string
    if ([aSearchbar.text length] > 0) {
        for (SiteInfo *item in self.sitesListResults) {
            if ([item.name rangeOfString:aSearchbar.text options:NSCaseInsensitiveSearch].location == NSNotFound ) {
                [searchResults removeObject:item];
            }
        }
        self.isShowingSearchResults = YES;
    } else {
        self.isShowingSearchResults = NO;
    }

    self.sitesListResults = searchResults;
    [self sortSitesForSiteListWithArray:self.sitesListResults];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

}

#pragma mark -
#pragma mark Data Source Loading / Reloading Methods

- (void)reloadTableViewDataSource{
	_reloading = YES;
    [self getSites];
}

- (void)doneLoadingTableViewData{
	//  model should call this when its done loading
	_reloading = NO;
	[_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];

    self.sitesSearchBar.text = SEARCH_BAR_EMPTY;
    self.navigationItem.title = ([self.sitesList count] > 1) ? NSLocalizedString(@"site_summaries_title", @"site_summaries_title") : NSLocalizedString(@"site_summary_title", @"site_summary_title");
}

#pragma mark -
#pragma mark UIScrollViewDelegate Methods

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

	[_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];
    [self.sitesSearchBar resignFirstResponder];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

	[_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];

}

#pragma mark -
#pragma mark EGORefreshTableHeaderDelegate Methods

- (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{

	[self performSelectorOnMainThread:@selector(reloadTableViewDataSource) withObject:nil waitUntilDone:NO];

    id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];

    [tracker send:[[GAIDictionaryBuilder createEventWithCategory:GA_EVENT_CATEGORY_GESTURE
                                                          action:GA_WITH_ACTION_PULL
                                                           label:@"refresh_sitelist_pull"
                                                           value:nil] build]];
}

- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{

	return _reloading; // should return if data source model is reloading

}

- (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{

	return [NSDate date]; // should return date data source was last changed

}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    if (self.noSiteAvailable) {
        return 1;
    } else {
        return 3;
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (self.noSiteAvailable) {
        return 1;
    } else {
        switch (section) {
            case 0:
                return self.sitesAlarmsCount;
                break;
            case 1:
                return self.sitesOkCount;
                break;
            case 2:
                return self.sitesOldCount;
                break;
            default:
                return 0;
                break;
        }
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    switch (section) {
        case 0:{
            if (self.sitesAlarmsCount) {
                return 76;
            }
            break;
        }
        case 1:{
            if (self.sitesOkCount) {
                return 76;
            }
            break;
        }
        case 2:{
            if (self.sitesOldCount) {
                return 76;
            }
            break;
        }
    }
    return 0;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (self.noSiteAvailable) {
        return 175.0f;
    } else {
        if (indexPath.section == 0) {
            return 120.0f;
        } else if (indexPath.section == 1) {
            return 120.0f;
        } else {
            return 70.0f;
        }
    }
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{

    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 76)];

    CGFloat sidePadding = 8;

    UIImageView *headerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(sidePadding, sidePadding * 2, self.view.frame.size.width - (sidePadding * 2), 60)];
    headerImageView.image = [[UIImage imageNamed:@"heading_corner.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(kHeaderInsetImageTop, kHeaderInsetImageLeft, kHeaderInsetImageBottom, kHeaderInsetImageRight)];

    [headerView addSubview:headerImageView];
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(16, 38, tableView.frame.size.width, 18)];
    [Tools style:LabelStyleSectionHeader forLabel:label];
    if(section == 0) {
        label.text = NSLocalizedString(@"status_alarm", @"status_alarm");
    } else if (section == 1){
        label.text = NSLocalizedString(@"status_ok", @"status_ok");
    }else {
        label.text = NSLocalizedString(@"status_old", @"status_old");
    }
    [headerView addSubview:label];
    [headerView setBackgroundColor:COLOR_BACKGROUND];

    return headerView;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.noSiteAvailable) {
        NoSitesAvailableCell *cell = (NoSitesAvailableCell *)[tableView dequeueReusableCellWithIdentifier:@"NoSitesAvailableCell"];
        return cell;
    } else {
        if (indexPath.section == 0) {
            SitesWithAlarmCell *cell = (SitesWithAlarmCell *)[tableView dequeueReusableCellWithIdentifier:@"SitesWithAlarmCell"];
            SiteInfo *info = [self.sitesListResults objectAtIndex:indexPath.row ];

            if (!info.siteAttributes && info.isLoadingWidgets) {
                [self getAttributesForSite:info withTableViewCell:cell];
            }
            [cell setDataWithSiteObject:info andTableView:tableView andIndexPath:indexPath andIsLoading:info.isLoadingWidgets];

            return cell;
        } else if (indexPath.section == 1) {
            SitesOKCell *cell = (SitesOKCell *)[tableView dequeueReusableCellWithIdentifier:@"SitesOKCell"];
            SiteInfo *info = [self.sitesListResults objectAtIndex:indexPath.row + self.sitesAlarmsCount];
            if (!info.siteAttributes && info.isLoadingWidgets) {
                [self getAttributesForSite:info withTableViewCell:cell];
            }
            [cell setDataWithSiteObject:info andTableView:tableView andIndexPath:indexPath andIsLoading:info.isLoadingWidgets];

            return cell;
        } else {
            SitesOutDatedCell *cell = (SitesOutDatedCell *)[tableView dequeueReusableCellWithIdentifier:@"SitesOutDatedCell"];
            SiteInfo *info = [self.sitesListResults objectAtIndex:indexPath.row + self.sitesAlarmsCount + self.sitesOkCount];
            [cell setDataWithSiteObject:info];
            return cell;
        }
    }

}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Empty the searchBar and remove the keyboard when a row is selected
    [self.sitesSearchBar setText:SEARCH_BAR_EMPTY];
    [self.sitesSearchBar resignFirstResponder];

    self.scrollViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"scrollView"];

    if (indexPath.section == 0) {
        self.selectedSite = [self.sitesListResults objectAtIndex:indexPath.row];
        self.scrollViewController.selectedSite = [self.sitesListResults objectAtIndex:indexPath.row];
        self.scrollViewController.siteIndex = [self.sitesList indexOfObject:self.selectedSite];
    } else if (indexPath.section == 1) {
        self.selectedSite = [self.sitesListResults objectAtIndex:indexPath.row + self.sitesAlarmsCount];
        self.scrollViewController.siteIndex = [self.sitesList indexOfObject:self.selectedSite];
        self.scrollViewController.selectedSite = [self.sitesListResults objectAtIndex:indexPath.row + self.sitesAlarmsCount];
    } else {
        self.selectedSite = [self.sitesListResults objectAtIndex:indexPath.row + self.sitesAlarmsCount + self.sitesOkCount];
        self.scrollViewController.selectedSite = [self.sitesListResults objectAtIndex:indexPath.row + self.sitesAlarmsCount + self.sitesOkCount];
        self.scrollViewController.siteIndex = [self.sitesList indexOfObject:self.selectedSite];
    }
    self.scrollViewController.sitesList = self.sitesList;

    self.indexOfSelectedSiteInList = [self.sitesList indexOfObject:self.selectedSite];

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        [self.navigationController pushViewController:self.scrollViewController animated:YES];
    } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

        // Send relevant Site Info to the detail view manager.
        self.detailViewManager.selectedSite = self.scrollViewController.selectedSite;
        self.detailViewManager.siteIndex = self.scrollViewController.siteIndex;
        self.detailViewManager.sitesList = self.scrollViewController.sitesList;

        // Tell the detail view manager to load a view controller with the selected site's details.
        [self.detailViewManager loadSelectedView];
    }

    // If we show searchresults en select a row we want to show all the sites again and show the selected site from the searchresults
    if (self.isShowingSearchResults) {
        [self sortSitesForSiteListWithArray:self.sitesList];
        [self scrollSiteListToSite:[self.sitesList indexOfObject:self.selectedSite] withDuration:0.0f];
        self.isShowingSearchResults = NO;
    } else {
        self.indexPathSite = indexPath;
    }

    id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];

    [tracker send:[[GAIDictionaryBuilder createEventWithCategory:GA_EVENT_CATEGORY_ACTION
                                                          action:GA_WITH_ACTION_LIST_PRESS
                                                           label:@"sitelist_list"
                                                           value:nil] build]];
}

-(void)getAttributesForSite:(SiteInfo *)siteInfo withTableViewCell:(UITableViewCell *)cell {

    [[M2MAttributesService new] loadSiteAttributesWithSiteID:@(siteInfo.siteID) success:^(AttributesInfo *attributes) {

        if (attributes) {
            siteInfo.siteAttributes = attributes;
            siteInfo.isLoadingWidgets = NO;
            [siteInfo setSummaryWidgetsforAttributes:attributes];
            [self reloadCellAfterFetchingWidgetsWithTableViewCell:cell];
        }
    } failure:^(NSInteger statusCode) {
        siteInfo.isLoadingWidgets = NO;
        NSLog(@"getAttributesForSite SiteListTableViewController. Status: %ld", (long)statusCode);
        [M2MNetworkErrorHandler checkToShowAlertViewForResponseCode:statusCode];
    }];
}

-(void) reloadCellAfterFetchingWidgetsWithTableViewCell:(UITableViewCell *)cell {
    // Check if the cell is still in the tableview, because we dont want to reload a cell that does not exist
    NSIndexPath *pathOfTheCellinblock = [self.tableView indexPathForCell:cell];
    if (pathOfTheCellinblock) {

        // Get the selected state of the cell before we reload it
        BOOL cellIsSelected = [self.tableView cellForRowAtIndexPath:pathOfTheCellinblock].selected;

        // Reload the cell
        [self.tableView reloadRowsAtIndexPaths:@[pathOfTheCellinblock] withRowAnimation:UITableViewRowAnimationNone];

        // Check if the cell was selected and if so we set the selected again after we reloaded it
        if (cellIsSelected) {
            [self.tableView selectRowAtIndexPath:pathOfTheCellinblock
                                        animated:NO
                                  scrollPosition:UITableViewScrollPositionNone];
        }
    }
}

- (BOOL)shouldAutorotate {
    return YES;
}

@end


text:
"""Support for performing TensorFlow classification on images."""
import io
import logging
import os
import sys
import time

from PIL import Image, ImageDraw, UnidentifiedImageError
import numpy as np
import tensorflow as tf  # pylint: disable=import-error
import voluptuous as vol

from homeassistant.components.image_processing import (
    CONF_CONFIDENCE,
    CONF_ENTITY_ID,
    CONF_NAME,
    CONF_SOURCE,
    PLATFORM_SCHEMA,
    ImageProcessingEntity,
)
from homeassistant.const import EVENT_HOMEASSISTANT_START
from homeassistant.core import split_entity_id
from homeassistant.helpers import template
import homeassistant.helpers.config_validation as cv
from homeassistant.util.pil import draw_box

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"

DOMAIN = "tensorflow"
_LOGGER = logging.getLogger(__name__)

ATTR_MATCHES = "matches"
ATTR_SUMMARY = "summary"
ATTR_TOTAL_MATCHES = "total_matches"
ATTR_PROCESS_TIME = "process_time"

CONF_AREA = "area"
CONF_BOTTOM = "bottom"
CONF_CATEGORIES = "categories"
CONF_CATEGORY = "category"
CONF_FILE_OUT = "file_out"
CONF_GRAPH = "graph"
CONF_LABELS = "labels"
CONF_LABEL_OFFSET = "label_offset"
CONF_LEFT = "left"
CONF_MODEL = "model"
CONF_MODEL_DIR = "model_dir"
CONF_RIGHT = "right"
CONF_TOP = "top"

AREA_SCHEMA = vol.Schema(
    {
        vol.Optional(CONF_BOTTOM, default=1): cv.small_float,
        vol.Optional(CONF_LEFT, default=0): cv.small_float,
        vol.Optional(CONF_RIGHT, default=1): cv.small_float,
        vol.Optional(CONF_TOP, default=0): cv.small_float,
    }
)

CATEGORY_SCHEMA = vol.Schema(
    {vol.Required(CONF_CATEGORY): cv.string, vol.Optional(CONF_AREA): AREA_SCHEMA}
)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Optional(CONF_FILE_OUT, default=[]): vol.All(cv.ensure_list, [cv.template]),
        vol.Required(CONF_MODEL): vol.Schema(
            {
                vol.Required(CONF_GRAPH): cv.isdir,
                vol.Optional(CONF_AREA): AREA_SCHEMA,
                vol.Optional(CONF_CATEGORIES, default=[]): vol.All(
                    cv.ensure_list, [vol.Any(cv.string, CATEGORY_SCHEMA)]
                ),
                vol.Optional(CONF_LABELS): cv.isfile,
                vol.Optional(CONF_LABEL_OFFSET, default=1): int,
                vol.Optional(CONF_MODEL_DIR): cv.isdir,
            }
        ),
    }
)

def get_model_detection_function(model):
    """Get a tf.function for detection."""

    @tf.function
    def detect_fn(image):
        """Detect objects in image."""

        image, shapes = model.preprocess(image)
        prediction_dict = model.predict(image, shapes)
        detections = model.postprocess(prediction_dict, shapes)

        return detections

    return detect_fn

def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the TensorFlow image processing platform."""
    model_config = config[CONF_MODEL]
    model_dir = model_config.get(CONF_MODEL_DIR) or hass.config.path("tensorflow")
    labels = model_config.get(CONF_LABELS) or hass.config.path(
        "tensorflow", "object_detection", "data", "mscoco_label_map.pbtxt"
    )
    checkpoint = os.path.join(model_config[CONF_GRAPH], "checkpoint")
    pipeline_config = os.path.join(model_config[CONF_GRAPH], "pipeline.config")

    # Make sure locations exist
    if (
        not os.path.isdir(model_dir)
        or not os.path.isdir(checkpoint)
        or not os.path.exists(pipeline_config)
        or not os.path.exists(labels)
    ):
        _LOGGER.error("Unable to locate tensorflow model or label map")
        return

    # append custom model path to sys.path
    sys.path.append(model_dir)

    try:
        # Verify that the TensorFlow Object Detection API is pre-installed
        # These imports shouldn't be moved to the top, because they depend on code from the model_dir.
        # (The model_dir is created during the manual setup process. See integration docs.)

        # pylint: disable=import-outside-toplevel
        from object_detection.builders import model_builder
        from object_detection.utils import config_util, label_map_util
    except ImportError:
        _LOGGER.error(
            "No TensorFlow Object Detection library found! Install or compile "
            "for your system following instructions here: "
            "https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2.md#installation"
        )
        return

    try:
        # Display warning that PIL will be used if no OpenCV is found.
        import cv2  # noqa: F401 pylint: disable=unused-import, import-outside-toplevel
    except ImportError:
        _LOGGER.warning(
            "No OpenCV library found. TensorFlow will process image with "
            "PIL at reduced resolution"
        )

    hass.data[DOMAIN] = {CONF_MODEL: None}

    def tensorflow_hass_start(_event):
        """Set up TensorFlow model on hass start."""
        start = time.perf_counter()

        # Load pipeline config and build a detection model
        pipeline_configs = config_util.get_configs_from_pipeline_file(pipeline_config)
        detection_model = model_builder.build(
            model_config=pipeline_configs["model"], is_training=False
        )

        # Restore checkpoint
        ckpt = tf.compat.v2.train.Checkpoint(model=detection_model)
        ckpt.restore(os.path.join(checkpoint, "ckpt-0")).expect_partial()

        _LOGGER.debug(
            "Model checkpoint restore took %d seconds", time.perf_counter() - start
        )

        model = get_model_detection_function(detection_model)

        # Preload model cache with empty image tensor
        inp = np.zeros([2160, 3840, 3], dtype=np.uint8)
        # The input needs to be a tensor, convert it using `tf.convert_to_tensor`.
        input_tensor = tf.convert_to_tensor(inp, dtype=tf.float32)
        # The model expects a batch of images, so add an axis with `tf.newaxis`.
        input_tensor = input_tensor[tf.newaxis, ...]
        # Run inference
        model(input_tensor)

        _LOGGER.debug("Model load took %d seconds", time.perf_counter() - start)
        hass.data[DOMAIN][CONF_MODEL] = model

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, tensorflow_hass_start)

    category_index = label_map_util.create_category_index_from_labelmap(
        labels, use_display_name=True
    )

    entities = []

    for camera in config[CONF_SOURCE]:
        entities.append(
            TensorFlowImageProcessor(
                hass,
                camera[CONF_ENTITY_ID],
                camera.get(CONF_NAME),
                category_index,
                config,
            )
        )

    add_entities(entities)

class TensorFlowImageProcessor(ImageProcessingEntity):
    """Representation of an TensorFlow image processor."""

    def __init__(
        self,
        hass,
        camera_entity,
        name,
        category_index,
        config,
    ):
        """Initialize the TensorFlow entity."""
        model_config = config.get(CONF_MODEL)
        self.hass = hass
        self._camera_entity = camera_entity
        if name:
            self._name = name
        else:
            self._name = "TensorFlow {}".format(split_entity_id(camera_entity)[1])
        self._category_index = category_index
        self._min_confidence = config.get(CONF_CONFIDENCE)
        self._file_out = config.get(CONF_FILE_OUT)

        # handle categories and specific detection areas
        self._label_id_offset = model_config.get(CONF_LABEL_OFFSET)
        categories = model_config.get(CONF_CATEGORIES)
        self._include_categories = []
        self._category_areas = {}
        for category in categories:
            if isinstance(category, dict):
                category_name = category.get(CONF_CATEGORY)
                category_area = category.get(CONF_AREA)
                self._include_categories.append(category_name)
                self._category_areas[category_name] = [0, 0, 1, 1]
                if category_area:
                    self._category_areas[category_name] = [
                        category_area.get(CONF_TOP),
                        category_area.get(CONF_LEFT),
                        category_area.get(CONF_BOTTOM),
                        category_area.get(CONF_RIGHT),
                    ]
            else:
                self._include_categories.append(category)
                self._category_areas[category] = [0, 0, 1, 1]

        # Handle global detection area
        self._area = [0, 0, 1, 1]
        area_config = model_config.get(CONF_AREA)
        if area_config:
            self._area = [
                area_config.get(CONF_TOP),
                area_config.get(CONF_LEFT),
                area_config.get(CONF_BOTTOM),
                area_config.get(CONF_RIGHT),
            ]

        template.attach(hass, self._file_out)

        self._matches = {}
        self._total_matches = 0
        self._last_image = None
        self._process_time = 0

    @property
    def camera_entity(self):
        """Return camera entity id from process pictures."""
        return self._camera_entity

    @property
    def name(self):
        """Return the name of the image processor."""
        return self._name

    @property
    def state(self):
        """Return the state of the entity."""
        return self._total_matches

    @property
    def extra_state_attributes(self):
        """Return device specific state attributes."""
        return {
            ATTR_MATCHES: self._matches,
            ATTR_SUMMARY: {
                category: len(values) for category, values in self._matches.items()
            },
            ATTR_TOTAL_MATCHES: self._total_matches,
            ATTR_PROCESS_TIME: self._process_time,
        }

    def _save_image(self, image, matches, paths):
        img = Image.open(io.BytesIO(bytearray(image))).convert("RGB")
        img_width, img_height = img.size
        draw = ImageDraw.Draw(img)

        # Draw custom global region/area
        if self._area != [0, 0, 1, 1]:
            draw_box(
                draw, self._area, img_width, img_height, "Detection Area", (0, 255, 255)
            )

        for category, values in matches.items():
            # Draw custom category regions/areas
            if category in self._category_areas and self._category_areas[category] != [
                0,
                0,
                1,
                1,
            ]:
                label = f"{category.capitalize()} Detection Area"
                draw_box(
                    draw,
                    self._category_areas[category],
                    img_width,
                    img_height,
                    label,
                    (0, 255, 0),
                )

            # Draw detected objects
            for instance in values:
                label = "{} {:.1f}%".format(category, instance["score"])
                draw_box(
                    draw, instance["box"], img_width, img_height, label, (255, 255, 0)
                )

        for path in paths:
            _LOGGER.info("Saving results image to %s", path)
            if not os.path.exists(os.path.dirname(path)):
                os.makedirs(os.path.dirname(path), exist_ok=True)
            img.save(path)

    def process_image(self, image):
        """Process the image."""
        model = self.hass.data[DOMAIN][CONF_MODEL]
        if not model:
            _LOGGER.debug("Model not yet ready")
            return

        start = time.perf_counter()
        try:
            import cv2  # pylint: disable=import-outside-toplevel

            img = cv2.imdecode(np.asarray(bytearray(image)), cv2.IMREAD_UNCHANGED)
            inp = img[:, :, [2, 1, 0]]  # BGR->RGB
            inp_expanded = inp.reshape(1, inp.shape[0], inp.shape[1], 3)
        except ImportError:
            try:
                img = Image.open(io.BytesIO(bytearray(image))).convert("RGB")
            except UnidentifiedImageError:
                _LOGGER.warning("Unable to process image, bad data")
                return
            img.thumbnail((460, 460), Image.ANTIALIAS)
            img_width, img_height = img.size
            inp = (
                np.array(img.getdata())
                .reshape((img_height, img_width, 3))
                .astype(np.uint8)
            )
            inp_expanded = np.expand_dims(inp, axis=0)

        # The input needs to be a tensor, convert it using `tf.convert_to_tensor`.
        input_tensor = tf.convert_to_tensor(inp_expanded, dtype=tf.float32)

        detections = model(input_tensor)
        boxes = detections["detection_boxes"][0].numpy()
        scores = detections["detection_scores"][0].numpy()
        classes = (
            detections["detection_classes"][0].numpy() + self._label_id_offset
        ).astype(int)

        matches = {}
        total_matches = 0
        for box, score, obj_class in zip(boxes, scores, classes):
            score = score * 100
            boxes = box.tolist()

            # Exclude matches below min confidence value
            if score < self._min_confidence:
                continue

            # Exclude matches outside global area definition
            if (
                boxes[0] < self._area[0]
                or boxes[1] < self._area[1]
                or boxes[2] > self._area[2]
                or boxes[3] > self._area[3]
            ):
                continue

            category = self._category_index[obj_class]["name"]

            # Exclude unlisted categories
            if self._include_categories and category not in self._include_categories:
                continue

            # Exclude matches outside category specific area definition
            if self._category_areas and (
                boxes[0] < self._category_areas[category][0]
                or boxes[1] < self._category_areas[category][1]
                or boxes[2] > self._category_areas[category][2]
                or boxes[3] > self._category_areas[category][3]
            ):
                continue

            # If we got here, we should include it
            if category not in matches:
                matches[category] = []
            matches[category].append({"score": float(score), "box": boxes})
            total_matches += 1

        # Save Images
        if total_matches and self._file_out:
            paths = []
            for path_template in self._file_out:
                if isinstance(path_template, template.Template):
                    paths.append(
                        path_template.render(camera_entity=self._camera_entity)
                    )
                else:
                    paths.append(path_template)
            self._save_image(image, matches, paths)

        self._matches = matches
        self._total_matches = total_matches
        self._process_time = time.perf_counter() - start


text:
The `load_graph` function in this directory changes to a subdirectory
of the data directory and attempts to call the loader defined there
(which should also be called `load_graph`).  Any arguments to this
`load_graph` are passed through to the loader in the subdirectory.


text:
<!--
 *******************************************************************************
 *
 * Copyright (c) 2004-2009 Oracle Corporation.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *
 *    Kohsuke Kawaguchi
 *
 *******************************************************************************
-->

<html><head/><body>
        Code that computes links to external source code repository browsers.
    </body></html>


text:
require 'securerandom'
require 'cgi'
require "timeout"
require "socket"

require 'active_support/core_ext/class/delegating_attributes'

require 'active_utils/common/network_connection_retries'
require 'active_utils/common/connection'
require 'active_utils/common/requires_parameters'
require 'active_utils/common/country'
require 'active_utils/common/error'
require 'active_utils/common/post_data'
require 'active_utils/common/posts_data'
require 'active_utils/common/currency_code'

require "offsite_payments/helper"
require "offsite_payments/notification"
require "offsite_payments/return"
require "offsite_payments/integrations"
require "offsite_payments/action_view_helper"

I18n.enforce_available_locales = false

module OffsitePayments
  # Return the matching integration module
  # You can then get the notification from the module
  # * <tt>bogus</tt>: Bogus - Does nothing (for testing)
  # * <tt>chronopay</tt>: Chronopay
  # * <tt>paypal</tt>: Paypal
  #
  #   chronopay = OffsitePayments.integration('chronopay')
  #   notification = chronopay.notification(raw_post)
  #
  def self.integration(name)
    Integrations.const_get("#{name.to_s.downcase}".camelize)
  end

  mattr_accessor :mode
  self.mode = :production

  # A check to see if we're in test mode
  def self.test?
    self.mode == :test
  end

  CURRENCIES_WITHOUT_FRACTIONS = [ 'BIF', 'BYR', 'CLP', 'CVE', 'DJF', 'GNF', 'HUF', 'ISK', 'JPY', 'KMF', 'KRW', 'PYG', 'RWF', 'TWD', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF' ]
end


text:
package com.amazon.ask.localdebug.constants;

/**
 * Class for constants.
 */
public final class Constants {
    /**
     * Private constructor.
     */
    private Constants() {
    }
    // Constants for user provided arguments.
    /**
     * Skill entry class argument name.
     */
    public static final String SKILL_ENTRY_CLASS_ARG_NAME = "skillStreamHandlerClass";
    /**
     * Skill id argument name.
     */
    public static final String SKILL_ID_ARG_NAME = "skillId";
    /**
     * LWA client id argument name.
     */
    public static final String ACCESS_TOKEN = "accessToken";
    /**
     * Thread pool size argument name.
     */
    public static final String THREAD_POOL_SIZE = "threadPoolSize";
    /**`
     * Region argument name.
     */
    public static final String REGION = "region";
    /**
     * Web socket connection uri skeleton.
     */
    public static final String CONNECT_CUSTOM_DEBUG_URI_SKELETON =
            "wss://%1$s/v1/skills/%2$s/stages/development/connectCustomDebugEndpoint";
    // Header constants for web socket connection request.
    /**
     * Upgrade header value.
     */
    public static final String UPGRADE_HEADER_VALUE = "websocket";
    /**
     * Upgrade header key.
     */
    public static final String UPGRADE_HEADER_NAME = "upgrade";
    /**
     * Connection header value.
     */
    public static final String CONNECTION_HEADER_VALUE = "upgrade";
    /**
     * Authorization header key.
     */
    public static final String AUTHORIZATION_HEADER_NAME = "authorization";
    /**
     * Connection header key.
     */
    public static final String CONNECTION_HEADER_NAME = "connection";
    /**
     * Default debugging region. Defaults to North America.
     */
    public static final String DEFAULT_REGION = "NA";
}