do


local CBP_oldRemoteViewing = RemoteViewing

function RemoteViewing(Superclass)
    local OldClass = CBP_oldRemoteViewing(Superclass)
    return Class(OldClass) {

        # Brute51: fixed a bug with the optics facility taking energy when trying to see something while the
        # building is paused [134].
        # while I was at it also implemented the means for a cooldown since I was going to do that in the balance
        # mod anyway. If you add a variable called 'Cooldown' in the intel table of the optics facility you can use
        # that to control the time beteen seeing different locations on the map. When the cooldown period is active
        # it cant change viewing locations. Another new feature is the viewtime. You can tell the optics facility 
        # how long to show a location and then stop viewing that. Use the variable 'Viewtime' in the intel table of
        # the units blueprint (same as prev value). If you use a value of 0 for any of these variables the feature 
        # is not used.
        # New feature in V4: growing (or shrinking) viewing radius. To use it add to the Intel category or the
        # units blueprint the variable 'RemoteViewingRadiusFinal'. This variable indicates the viewing radius after
        # growing. Use a negative value to shrink the viewing radius instead. You can control the rate of growth
        # with another blueprint variable called 'RadiusGrowStepSize' in the same section. This defaults to 1
        # which means the viewing radius grows 1 unit per tick.

        # added by brute51 - a cooldown period. the vision marker cannot be changed during the is period
        Cooldown = function(self, time)
            if time > 0 then
                self.Sync.Abilities = self:GetBlueprint().Abilities # dont use self:DisableRemoteViewingButtons(), that introduces a bug when using multiple remote viewing units
                self.Sync.Abilities.TargetLocation.Active = false
                self:RemoveToggleCap('RULEUTC_IntelToggle')
                WaitSeconds(time)
                self.Sync.Abilities = self:GetBlueprint().Abilities # dont use self:EnableRemoteViewingButtons()
                self.Sync.Abilities.TargetLocation.Active = true
                self:AddToggleCap('RULEUTC_IntelToggle')
            end
        end,

        # added by brute51 - an auto disable feature. removes the view after a set period
        Viewtime = function(self, viewtime)
            if viewtime > 0 then
                WaitSeconds(viewtime)
                self:DisableVisibleEntity()
            end
        end,

        # added by brute51 - changes the size of the camera each tick. Should be able to handle growing and shrinking
        ViewingRadius = function(self, initialRadius, endingRadius, step)
            local sat = self.RemoteViewingData.Satellite
            local nTicks = math.ceil( (endingRadius - initialRadius) / step )
            if initialRadius > endingRadius then
                step = math.min( step, -step)  # make sure we get a negative stepsize
                nTicks = -nTicks
            end
            sat:SetIntelRadius('vision', initialRadius)
            local curRadius = initialRadius
            for i=1, nTicks do
                WaitTicks(1)
                if not sat or sat:BeenDestroyed() then return end
                curRadius = curRadius + step
                sat:SetIntelRadius('vision', curRadius)
            end
            sat:SetIntelRadius('vision', endingRadius)
        end,

        CreateVisibleEntity = function(self)
            local VisibilityEntityWillBeCreated = (self.RemoteViewingData.VisibleLocation and self.RemoteViewingData.DisableCounter == 0 and self.RemoteViewingData.IntelButton)
            OldClass.CreateVisibleEntity(self)
            if VisibilityEntityWillBeCreated then     # added by brute51
                local bp = self:GetBlueprint().Intel
                if bp.Cooldown and bp.Cooldown > 0 then
                    self.CooldownThread = self:ForkThread(self.Cooldown, bp.Cooldown)  # cooldown
                    self.Trash:Add(self.CooldownThread)
                end
                if bp.Viewtime and bp.Viewtime > 0 then
                    self.ViewtimeThread = self:ForkThread(self.Viewtime, bp.Viewtime)  # auto-remove view
                    self.Trash:Add(self.ViewtimeThread)
                end
                if bp.RemoteViewingRadiusFinal and bp.RemoteViewingRadiusFinal > 0 and bp.RemoteViewingRadiusFinal != bp.RemoteViewingRadius then
                    # for a growing viewing radius
                    local initRadius = bp.RemoteViewingRadius
                    local finalRadius = bp.RemoteViewingRadiusFinal
                    local step = bp.RadiusGrowStepSize or 0.2
                    self.ViewingRadiusThread = self:ForkThread(self.ViewingRadius, initRadius, finalRadius, step)
                    self.Trash:Add(self.ViewingRadiusThread)
                end
            end
        end,

        OnTargetLocation = function(self, location)
            if self.RemoteViewingData.IntelButton then # added by brute51 - bug fix [134]
                OldClass.OnTargetLocation(self, location)
            end
        end,

        OnCreate = function(self)
            OldClass.OnCreate(self)
            # makes sure all scrying buttons are visible. sometimes they don't become visible by themselves.
            self.Sync.Abilities = self:GetBlueprint().Abilities # dont use self:EnableRemoteViewingButtons()
            self.Sync.Abilities.TargetLocation.Active = true
            self:AddToggleCap('RULEUTC_IntelToggle')
        end,

        DisableVisibleEntity = function(self)
            OldClass.DisableVisibleEntity(self)
            # kill any thread that isn't used anymore
            if self.ViewtimeThread then
                KillThread(self.ViewtimeThread)
            end
            if self.ViewingRadiusThread then
                KillThread(self.ViewingRadiusThread)
            end
        end,
    }    
end

end