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)
    self.range = range
    self.fixed_coord = {x=self.x, y=self.y}
end

function viewport:free_move()
    self.range = nil
    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
            self.x = nx
            if self.smooth_adjust.x~=nil then
                if nx<self.smooth_adjust.x-self.adjust_speed then
                    self.x=self.smooth_adjust.x-self.adjust_speed
                    self.smooth_adjust.x=self.smooth_adjust.x-self.adjust_speed
                elseif nx>self.smooth_adjust.x+self.adjust_speed then
                    self.x=self.smooth_adjust.x+self.adjust_speed
                    self.smooth_adjust.x=self.smooth_adjust.x+self.adjust_speed
                elseif math.abs(nx-self.smooth_adjust.x)<self.adjust_speed then
                    self.smooth_adjust.x = nil
                end
            end
            
            self.y = ny
            if self.smooth_adjust.y~=nil then
                if ny<self.smooth_adjust.y-self.adjust_speed then
                    self.y=self.smooth_adjust.y-self.adjust_speed
                    self.smooth_adjust.y=self.smooth_adjust.y-self.adjust_speed
                elseif ny>self.smooth_adjust.y+self.adjust_speed then
                    self.y=self.smooth_adjust.y+self.adjust_speed
                    self.smooth_adjust.y=self.smooth_adjust.y-self.adjust_speed
                elseif math.abs(ny-self.smooth_adjust.y)<self.adjust_speed then
                    self.smooth_adjust.y = nil
                end
            end
            
            if self.smooth_adjust.x == nil and self.smooth_adjust.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