# -*- coding: UTF-8 -*-
#    This file is part of arena.
#   
#    arena is free software: you can redistribute it and/or modify it
#    under the terms of the GNU General Public License as published by the
#    Free Software Foundation; either version 3 of the License or, at your
#    option, any later version.
#
#    arena is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABLITY
#    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
#    License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with arena.  If not, see <http://www.gnu.org/licenses/>. 

## @file
#  This file defines an application class that handles a CGI environment which
#  buffers its output.

from Library.Application.CGIApplications import ACGIApplication
from Library.IO.CGI.BufferedResponses import AnHTTPResponseBuffer
import sys

## A CGI application that buffers its output.
#    
#  This class changes `sys.stdout` to point to its output buffer, so that calls
#  to `print()` will be directed to the output buffer instead of the console or
#  other output device.
#   
#  In addition to constructing the buffered output handler, this class also
#  ensures that the values of its `Cookie` attribute are passed to the
#  output handler, so that cookies can easily be updated by the application.
class ABufferedCGIApplication(ACGIApplication):
    ## Constructor   
    def __init__(Self, **arguments):
        ACGIApplication.__init__(Self, *arguments)
        
    ## Initializer
    def init(Self):
        result = ACGIApplication.init(Self)
        
        if result == True:
            # Establish private attributes
            # The output buffer
            Self._Output = AnHTTPResponseBuffer()
            ## The previous value of sys.stdout
            Self._stdout = sys.stdout
            sys.stdout = Self._Output
            
        return result
        
    ## Destructor
    def __del__(Self):
        # Free the output buffer
        sys.stdout = Self._stdout
        del Self._Output
        
        ACGIApplication.__del__(Self)
        
    ## Print the output buffer to the specified stream or stdout if
    #  no stream is specified.
    def flush(Self, ThisStream=None):
        # Transfer our cookies to the output buffer
        Self._Output.Cookie = Self.Cookie
        
        if ThisStream is None:
            Self._stdout.write(Self._Output.toString())
            
        else:
            ThisStream.write(Self._Output.toString())
            
    ## Display an error that may occur while running the engine.
    def displayError(Self, Err):
        Self._Output.write(str(Err))            
        
    # Properties ---------------------------------------------------------------
    ## Retrieve the output buffer used by the application. 
    def Output(Self):
        return Self._Output
        
