require "map"

viewport={}

function viewport.new(_width, _height)
    return { x=0, y=0,
	         width=_width,
			 height=_height,
             get=viewport.get,
			 position=viewport.position,
			 print=viewport.print,
			 room=viewport.coord2room,
             --roomXY= viewport.room2coord,
             tile= viewport.tile,
             last_tile= viewport.last_tile,
             screen_coords = viewport.screen_coords,
             inside = viewport.inside,
             fixed = viewport.fixed,
             free_move = viewport.free_move,
             range = nil,       -- rang de moviment quan està fixat {r= , l=, u=, d= }
             fixed_coord = nil, -- coordenades fixades
             smooth_adjust = nil,
             adjust_speed = 2
           } 
end

function viewport:fixed(range, _x, _y)
    self.range = range
    _x = _x or self.x
    _y = _y or self.y
    self.fixed_coord = {x=_x, y=_y}
end

function viewport:free_move()
    self.range = nil
    if self.fixed_coord~=nil then print ("FIXED COORD= "..self.fixed_coord.x..", "..self.fixed_coord.y) end
    self.smooth_adjust = self.fixed_coord
    self.fixed_coord = nil
end

function viewport:get()
    return self.x, self.y, self.x+self.width, self.y+self.height
end

function viewport:screen_coords ( x, y )
    local scr_x = x-self.x
    local scr_y = y-self.y
    return scr_x, scr_y
end

function viewport:inside( x, y, w, h )
    local result = false
    if self.x<=x+w and self.x+self.width>=x and self.y<=y+h and self.y+self.height>=y then result = true end
    return result
end

function viewport:tile ()
    return coords.world_to_tile(self.x, self.y)
end

function viewport:last_tile ()
    return coords.world_to_tile(self.x+self.width, self.y+self.height)
end

function viewport:coord2room ()
    return coords.world_to_room(self.x, self.y)
end

function viewport:position(x, y)
  local nx = (x ~= nil) and x or self.x
  local ny = (y ~= nil) and y or self.y

    if self.range==nil then
        if self.smooth_adjust == nil then
            self.x = nx
            self.y = ny
        else
            -- viewport lliure després de fixar-lo -> Ajustar suau
            local speed_x = self.adjust_speed
            local speed_y = self.adjust_speed
            local sm_x  = self.smooth_adjust.x
            local sm_y  = self.smooth_adjust.y
            self.x = nx
            if sm_x~=nil then
                if math.abs(nx-sm_x)<speed_x then
                    sm_x = nil
                else
                    if nx<sm_x-speed_x then speed_x = -speed_x end
                    self.x=sm_x+speed_x
                    sm_x  =sm_x+speed_x
                end
                self.smooth_adjust.x = sm_x
            end
            
            self.y = ny
            if sm_y~=nil then
                if math.abs(ny-sm_y)<speed_y then
                    sm_y = nil
                else
                    if ny<sm_y-speed_y then speed_y = -speed_y end
                    self.y=sm_y+speed_y
                    sm_y  =sm_y+speed_y
                end
                self.smooth_adjust.y = sm_y
            end
            
            if sm_x == nil and sm_y == nil then
                self.smooth_adjust = nil
            end
        end
    else
        -- viewport fixe
        self.x = nx
        -- moure viewport left - right
        if nx<self.fixed_coord.x-self.range.l then
            self.x = self.fixed_coord.x-self.range.l
        elseif nx>self.fixed_coord.x+self.range.r then
            self.x = self.fixed_coord.x+self.range.r
        end

        self.y = ny
        -- moure viewport up - down
        if ny<self.fixed_coord.y-self.range.u then
            self.y = self.fixed_coord.y-self.range.u
        elseif ny>self.fixed_coord.y+self.range.d then
            self.y = self.fixed_coord.y+self.range.d
        end
    end

  return self.x, self.y
end

function viewport:print()
	local room = self:room()
	draw.rectf(0,7,45,14,16)
    draw.text("X="..self.x.." , Y= "..self.y..", R"..room,1,8,2)
end

return viewport