//
//  Game.swift
//  sleazyburger
//
//  Created by Aslak Gronflaten on 1/24/15.
//  Copyright (c) 2015 Javelin. All rights reserved.
//

import Foundation
import SpriteKit

enum BodyType : UInt32 {
    case ground = 1
    case burger = 2
}

var score = 0

class Game : NSObject, SKPhysicsContactDelegate {
    let scene : SKScene
    let view : SKView
    let plateX : CGFloat = 220
    
//    let parts = ["bottom", "tomato_slice_600.png", "cheese", "patty", "salad", "top"]
    
    let parts = ["midbun_iso_600", "patty_iso_600",  "tomato_iso_500","cheese_iso_600"]
    let requests = ["Bread", "Meat", "Tomato", "Cheese"]
    
    var outroDelegate : OutroDelegate?
    var textures : [SKTexture] = []
    var partIndex = 0
    var partCount = 0
    var world : World = World()
    var scaleIt = false
    var ingredients : [SKSpriteNode] = []
    var scoreLabel : SKLabelNode
    let speech : SpeechBubble
    var requested = -1
    var redColor : SKColor = SKColor.redColor()
    var blackColor : SKColor = SKColor.blackColor()
    var greenColor : SKColor = SKColor.greenColor()
    var zPos :UInt8 = 0
    
    func didBeginContact(contact: SKPhysicsContact) {
    }
    
    func makeColorRed(red : Int, green: Int, blue: Int) -> SKColor {
        let r : CGFloat = CGFloat(red)/255.0
        let g = CGFloat(green)/255.0
        let b = CGFloat(blue)/255.0
        return SKColor(red: r, green: g, blue: b, alpha: 1.0)
    }
    
    init(scene : SKScene, view: SKView, scaleIt: Bool) {
        self.view = view
        self.scene = scene
        let frame = view.frame
        self.scaleIt = scaleIt
        speech = SpeechBubble(dummy: false)
        scoreLabel = SKLabelNode(text: "Score: 0")
        super.init()
        redColor = makeColorRed(236, green: 28, blue: 36)
        blackColor = makeColorRed(35, green: 35, blue: 35)
        greenColor = makeColorRed(0, green: 165, blue: 81)

        scoreLabel.fontName = "Marker Felt Wide"
        scoreLabel.position = CGPointMake(134, 720)
        scoreLabel.fontColor = blackColor

        
        // Load textures for burger bits
        for p in parts {
            let t = SKTexture(imageNamed: p)
            textures.append(t)
        }
        partCount = textures.count

        view.showsPhysics = false
        let plateHeight : CGFloat = 50
        let table = SKPhysicsBody(edgeFromPoint: CGPointMake(0, plateHeight), toPoint: CGPointMake(1024, plateHeight))
        world.physicsBody = table
        table.collisionBitMask = BodyType.burger.rawValue
        table.categoryBitMask = BodyType.ground.rawValue
        table.contactTestBitMask = BodyType.burger.rawValue
        
        let floorY : CGFloat = 40
        world.position.y = floorY

        
        
        let bg = SKSpriteNode(imageNamed: "playarea_bg_1024x768")
        bg.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
        scene.addChild(bg)
        scene.addChild(scoreLabel)
        scene.addChild(world)


        let plate = SKSpriteNode(imageNamed: "plate_800w")
        plate.position = CGPointMake(plateX, floorY)
        world.addChild(plate)

        let bun = SKSpriteNode(imageNamed: "bottombun_iso_650.png")
        bun.position = CGPointMake(plateX, 600)
        world.addChild(bun)
        var bunSize = bun.frame.size
        bunSize.height /= 3
        bun.physicsBody = SKPhysicsBody(rectangleOfSize: bunSize)
        scene.addChild(speech)
        speech.zPosition = 100
        setupShelf()
        scene.physicsWorld.contactDelegate = self
        world.game = self

    }
    
    func setupShelf() {
        // Set up a shelf with all the ingredients
        let x = CGFloat(830)
        var y = CGFloat(140)
        
        for p in textures {
            let s = SKSpriteNode(texture: p)
            if scaleIt {
                s.setScale(0.5)
            }
            s.position = CGPointMake(x, y)
            y += 130
            ingredients.append(s)
            scene.addChild(s)
        }
    }
    
    func getPartAt(point : CGPoint) -> SKSpriteNode? {
        for i in ingredients {
            if CGRectContainsPoint(i.frame, point) {
                // Clone it for now for simplicity
                var p = point
                p.y -= world.position.y
                let s = makeSprite(p, texture: i.texture!)
                return s
            }
        }
        return nil
    }
    
    func makeSprite(point : CGPoint, texture : SKTexture) -> SKSpriteNode {
        let s = SKSpriteNode(texture: texture)
        if scaleIt {
            s.setScale(0.5)
        }

        world.addBurger(s)
        s.position = point

        s.zPosition = CGFloat(zPos++)
        addPhysics(s)
        return s
    }
    
    func addPhysics(sprite : SKSpriteNode) {
        var size = sprite.frame.size
        if scaleIt {
            //            size.width /= 2
            //            size.height /= 2
        }
        size.height /= 2
        let body = SKPhysicsBody(rectangleOfSize: size)
        sprite.physicsBody = body
        body.dynamic = false
        
        body.collisionBitMask = BodyType.burger.rawValue | BodyType.ground.rawValue
        body.categoryBitMask = BodyType.burger.rawValue
        body.contactTestBitMask = BodyType.ground.rawValue
    }
    
    func droppedPart(sprite : SKSpriteNode) {
        // Check if part dropped is the correct 
        var correct = (requested == -1)
        for i in 0..<requests.count {
            if sprite.texture == textures[i] {
                if i == requested {
                    correct = true
                }
            }
        }
        sprite.physicsBody?.dynamic = true
        if correct {
            score++
            scoreLabel.fontColor = blackColor
        } else {
            if score > 0 {
                score -= 1
            }
            scoreLabel.fontColor = redColor
        }

        scoreLabel.text = "Score: \(score)"
        
        
        requested = Int(arc4random()) % partCount
        let req = requests[requested]
        speech.speak("\(req)!")
    }
    
    func clickAt(point : CGPoint) {
        let t = textures[partIndex]
        partIndex = ( partIndex + 1 ) %  partCount
        var size = t.size()
        if scaleIt {
            size.width /= 2
            size.height /= 2
        }
        let s = SKSpriteNode(texture: t)
        if scaleIt {
            s.setScale(0.5)
        }
        let body = SKPhysicsBody(rectangleOfSize: size)
        s.physicsBody = body
        s.position = point
        world.addBurger(s)
    }
    
    func outro() {
        let o = Outro(game: self)
        o.outroDelegate = outroDelegate
        view.presentScene(o)
        scene.removeAllActions()
        scene.removeAllChildren()
    }

}