"""
A simple way of setting the output format for data from modules
"""
import pprint

# Conditionally import the json and yaml modules
try:
    import json
    JSON = True
except ImportError:
    JSON = False
try:
    import yaml
    YAML = True
except ImportError:
    YAML = False

__all__ = ('get_outputter',)

class Outputter(object):
    """
    Class for outputting data to the screen.
    """
    supports = None

    @classmethod
    def check(klass, name):
       # Don't advertise Outputter classes for optional modules
       if hasattr(klass, "enabled") and not klass.enabled:
           return False
       return klass.supports == name

    def __call__(self, data, **kwargs):
        print "Calling Outputter.__call__()"
        pprint.pprint(data)

class TxtOutputter(Outputter):
    """
    Plain text output. Primarily for returning output from
    shell commands in the exact same way they would output
    on the shell when ran directly.
    """
    supports = "txt"
    def __call__(self, data, **kwargs):
        if hasattr(data, "keys"):
            for key in data.keys():
                value = data[key]
                for line in value.split('\n'):
                    print "{0}: {1}".format(key, line)
        else:
            # For non-dictionary data, run pprint
            super(TxtOutputter, self).__call__(data)

class JSONOutputter(Outputter):
    """JSON output. Chokes on non-serializable objects."""
    supports = "json"
    enabled  = JSON

    def __call__(self, data, **kwargs):
        try:
            # A good kwarg might be: indent=4
            print json.dumps(data, **kwargs)
        except TypeError:
            super(JSONOutputter, self).__call__(data)

class YamlOutputter(Outputter):
    """Yaml output. All of the cool kids are doing it."""
    supports = "yaml"
    enabled  = YAML

    def __call__(self, data,  **kwargs):
        print yaml.dump(data, **kwargs)

class RawOutputter(Outputter):
    """Raw output. This calls repr() on the returned data."""
    supports = "raw"
    def __call__(self, data, **kwargs):
        print data

def get_outputter(name=None):
    """
    Factory function for returning the right output class.

    Usage:
        printout = get_outputter("txt")
        printout(ret)
    """
    # Return an actual instance of the correct output class
    for i in Outputter.__subclasses__():
        if i.check(name):
            return i()
    return Outputter()

@@ -1,11 +1,11 @@
-%22%22%22
+'''
 %0AA simpl
@@ -61,19 +61,31 @@
 modules%0A
-%22%22%22
+'''%0Aimport yaml
 %0Aimport 
@@ -128,24 +128,14 @@
 son 
-and yaml 
 module
-s
 %0Atry
@@ -208,82 +208,8 @@
 alse
-%0Atry:%0A    import yaml%0A    YAML = True%0Aexcept ImportError:%0A    YAML = False
 %0A%0A__
@@ -261,27 +261,27 @@
 bject):%0A    
-%22%22%22
+'''
 %0A    Class f
@@ -314,27 +314,27 @@
 screen.%0A    
-%22%22%22
+'''
 %0A    support
@@ -625,44 +625,192 @@
     
+p
 print
- %22Calling Outputter.__call__()%22
+.pprint(data)%0A%0Aclass RawOutputter(Outputter):%0A    '''%0A    Raw output. This calls repr() on the returned data.%0A    '''%0A    supports = %22raw%22%0A    def __call__(self, data, **kwargs):
 %0A   
@@ -814,35 +814,26 @@
         
-p
 print
-.pprint(
+ 
 data
-)
 %0A%0Aclass 
@@ -857,27 +857,27 @@
 utter):%0A    
-%22%22%22
+'''
 %0A    Plain t
@@ -1019,27 +1019,27 @@
 rectly.%0A    
-%22%22%22
+'''
 %0A    support
@@ -1351,13 +1351,17 @@
 ta, 
-run p
+just use 
 prin
@@ -1378,42 +1378,22 @@
     
-super(TxtOutputter, self).__call__
+RawOutputter()
 (dat
@@ -1432,19 +1432,24 @@
 r):%0A    
-%22%22%22
+'''%0A    
 JSON out
@@ -1456,47 +1456,16 @@
 put.
- Chokes on non-serializable objects.%22%22%22
+%0A    '''
 %0A   
@@ -1615,21 +1615,21 @@
         
-print
+ret =
  json.du
@@ -1690,49 +1690,105 @@
     
-super(JSONOutputter, self).__call__(data)
+# Return valid json for unserializable objects%0A            ret = json.dumps(%7B%7D)%0A        print ret
 %0A%0Acl
@@ -1821,19 +1821,24 @@
 r):%0A    
-%22%22%22
+'''%0A    
 Yaml out
@@ -1876,19 +1876,24 @@
 oing it.
-%22%22%22
+%0A    '''
 %0A    sup
@@ -1910,28 +1910,8 @@
 aml%22
-%0A    enabled  = YAML
 %0A%0A  
@@ -1994,182 +1994,8 @@
 s)%0A%0A
-class RawOutputter(Outputter):%0A    %22%22%22Raw output. This calls repr() on the returned data.%22%22%22%0A    supports = %22raw%22%0A    def __call__(self, data, **kwargs):%0A        print data%0A%0A
 def 
@@ -2020,27 +2020,27 @@
 =None):%0A    
-%22%22%22
+'''
 %0A    Factory
@@ -2169,11 +2169,11 @@
     
-%22%22%22
+'''
 %0A   

Fix the coding style of salt.output and a few nits