/**
 * \file
 * <!--
 * Copyright 2004,2005,2006,2008 Develer S.r.l. (http://www.develer.com/)
 * All rights reserved.
 * -->
 *
 * \version $Id: coding_style.cpp 22211 2008-08-04 09:59:02Z bernie $
 * \author Bernie Innocenti <bernie@codewiz.org>
 * \author Simone Zinanni <s.zinanni@develer.com>
 * \author Stefano Fedrigo <aleph@develer.com>
 *
 *
 * \brief Develer indentation and naming style for C/C++-like languages.
 *
 * General rules:
 *
 *  - Begin all new files with standard headers like this one;
 *
 *  - For substantial edits to existing files, remember to update the
 *    copyright years and add yourself to list of authors;
 *
 *  - Use meaningful and descriptive commit log messages;
 *
 *  - Use correct capitalization and punctuation even in comments
 *    and in commit log messages.
 *
 *
 * Naming conventions quick reference:
 *
 *   - ClassName::memberFunction(const TypeName &arg_name);
 *
 *   - ClassName::member_variable
 *     ClassName::_private_member_variable_with_accessor
 *
 *   - static const int CONSTANT_VALUE = 42;
 *     enum { ALSO_A_CONSTANT = CONSTANT_VALUUE * 666 };
 *     \#define YET_ANOTHER_CONSTANT (CONSTANT_VALUE * ALSO_A_CONSTANT)
 *
 *   - template <class Cont, class Iter, typename T>
 *     void foo();
 */

/*
 * Place local header inclusions before system headers because it helps
 * catching local headers which don't stand on their own.
 *
 * Preferably add a comment to each system header to make it clear why
 * you're including it. It helps tracking which headers can be dropped
 * while performing maintainance work.
 */
#include "local.h"
#include "develer/stuff.h"

#include <iostream> // std::cout
#include <unistd.h> // open(), write()
#include <vector.h> // BAD: Don't use pre-ISO C++ 98 headers

/*
 * GOOD: import only what you really use often. Use the std prefix
 * for things you use sparingly.
 */
using std::string;
using std::cout;

/*
 * BAD: don't import _everything_ from the std namespace unless you
 * really need *lots* of stuff from it.
 *
 * Polluting the namespace with "using" in public interface headers is BAD.
 * Use explicit namespace qualification instead.
 */
using namespace std;


// Indent preprocessor commands like this:
#ifdef __WIN32__

        #define SEPARATOR '\\'
        #define BLA 42
        #define BOO(x) ((x) * 3)
        void myfunc(SOCKET socket);

#else // !__WIN32__

        #define SEPARATOR '/'
        #define BLA /*nop*/
        #define BOO(x) (0)
        void nuke_host(int socket);

#endif // !__WIN32__


/// Global variables are lower case, and have a unique, distinctive name:
int serial_fd;
std::list<Window *> window_list;

/**
 * Use English words for variable and class names if possible.
 * Common abbreviations and acronyms are allowed.
 *
 * English is also the preferred language for output messages,
 * comments and documentation. Some projects may override this
 * rule to satisfy client request.
 */
static struct UserAccount default_system_user;


// fwd decl
class MainWindow;

/**
 * Document all public classes briefly (use Doxygen's auto-brief feature).
 *
 * Write a detailed description of the class
 * general design, its role, and the intended use.
 *
 * \note Use Doxygen markup sparingly and consistently.
 *       Use JavaDoc style markup only in Java code.
 */
class FooBar : public Base
{
/*
 * Place public definitions first in class bodies.
 */

// public definitions
public:
        /// Constants and enum labels are all in UPPERCASE.
        static const int FOO_BAR_LENGTH = 100;

        /// Color, not Colors (avoid plurals).
        enum Color
        {
                NONE = -1,          ///< Document only non-obvious values.
                TRANSPARENT = -2,   ///< Don't use TABs to align comments.

                RED = 0,
                GREEN,
                BLUE,
                CYAN,
                MAGENTA,
                YELLOW,

                COLOR_CNT          ///< Total number of available colors.
        };

        /**
         * Document interface structures.
         */
        struct Point
        {
                int x, y; ///< Document x and y
                int color; ///< Document the color
        };

        /// Also document other public definitions.
        typedef std::vector<int> container_type;

/*
 * Public, protected and private data members should be
 * placed right after definitions and before member functions.
 */

// public data members
public:
        /// Size of FooBar (in millibars).
        size_t size;

        /// Don't capitalize member variables. Use underscores to break words.
        std::string multi_word_name;

        /// BAD: don't ever use hungarian notation and capitalization!
        LPCSTR lpszSomeVariableName;

// protected data members
protected:

        /**
         * Non-public attributes with "get" or "set" accessors are named after
         * their accessors, prefixed with an underscore to avoid using them
         * directly.
         */
        int _color;

        /// Non-public attributes without accessors don't need a prefix.
        int fuzzyness;

/*
 * Public member functions come before protected and private members.
 * Constructors are placed before any other member functions.
 */

// construction
public:
        // default ctor
        FooBar() { /* nop */ }

        /**
         * Some constructors need to be documented, others might be too simple
         * to be worth it.
         */
        FooBar(int color, int shape) :
                Base(shape)
        {
                this.color = color;
        };

        // vdtor
        virtual ~FooBar();

// public methods
public:
        /**
         * Document interface methods.
         *
         * \param file_name  Also document their parameters.
         * \param write      Unless their meaning is obvious.
         */
        void methodName(const char *file_name, bool write = false);

        /// You can also use one-liners for simple interfaces.
        inline bool anInlineMethod(void *buf)
        {
                // Declare main variables at the top of the function body.
                bool result = false;
                int iterations_cnt = 100;


                // BAD: don't use old-style casts
                char *avoid_this = (char *)buf;

                // GOOD: use new-style casts only
                char *str = static_cast<char *>(buf);

                /*
                 * For consistency with STL iterators, prefer pre-increment
                 * over post-increment when it does not make any difference.
                 */
                for (int i = 0; i < strlen(str); ++i)
                {
                        /*
                         * Place a space between if, for, while and the
                         * opening parentheses.
                         */
                        if (str[i] == 'a')
                                std::cout << str[i] << std::endl;
                }

                Window *w = getWindow();
                FileWindow *file_window;
                if ((fw = dynamic_cast<FileWindow *>(file_window)))
                {
                        fw->open();

                        /* Break long lines like this.
                         *
                         * We don't enforce a strict limit for the right margin;
                         * use common sense to improve readability.
                         */
                        if ((fw->selectedFile() && !(fw->userAbort()))
                                || (fw->multipleSelection
                                        && fw->filesSelected() > 2))
                        {
                                if (!resume_from_errors)
                                        panic();
                        }
                        else
                        {
                                // success
                                result = true;
                        }

                        fw->close();
                }

                return result;
        }

        void indentationExample()
        {
                /*
                 * GOOD: Always use TABs to indent your code.
                 *
                 * You can use whatever TAB size you prefer (usually 4 or 8).
                 */

               /*
                  * BAD: Don't mix TABs and spaces!
                    * If you do, your code will look like shit on anything but your editor.
                    * Here, we've set the editor with a TAB size of 6.
                    */

                // BAD: Don't leave hidden extra blanks before EOLs            
                
                /*
                 * GOOD: Use spaces instead of TABs for drawings and tables
                 *
                 *   VCC     Vref
                 *    |       |
                 *   +-+      |
                 *   | | Rk   |
                 *   | |      |
                 *   +-+      | +-----+
                 *    |       +-| ADC |
                 * V1 +---------|     |
                 *    |         +-----+
                 *   /// GND
                 */

                /*
                 * GOOD: Use TABs _only_ for indentation, and spaces only
                 * for formatting columns and tables of aligned values.
                 */
                const float NTC_MIN_TEMP    =  5.5;  ///< Minimum temperature    (Celsius degrees)
                const float NTC_MAX_TEMP    = 49.0;  ///< Maximum temperature    (Celsius degrees)
                const int   NTC_STEP        =  2;    ///< Increase between steps (ADC units)
                const int   NTC_STEPS_COUNT = (NTC_MAX_TEMP - NTC_MIN_TEMP) / NTC_STEP;
        }

// public accessors
public:
        /// Accessor to get an attribute (NOTE: No "get" prefix).
        int color() const { return _color; }

        /// Accessor to set an attribute (NOTE: Use "set" prefix).
        int setColor(int c) { _color = c; }

// disable unused default/copy constructors and assignment operator
private:
        //FooBar();
        FooBar(const FooBar &);
        FooBar &operator=(const FooBar &);
};


/// Out-of-line declaration.

void FooBar::methodName(const char *file_name, bool write /* = false */)
{
        try
        {
                Socket s(file_name, write);

                s.write("Hello, world!\n");
        }
        catch (io_exception &e)
        {
                std::cout << "Error!\n";
                throw e;
        }
}


/**
 * \name Foo handling.
 *
 * When you are using a procedural language such as C and you need to group a
 * set of functions operating on the same entity, these functions must be
 * prefixed with the (short) name of the module they refer to:
 *
 * \{
 */
extern void foo_open(void);
extern void foo_close(void);
extern void foo_isOpen(void);
extern void foo_getSize(void);
//\}

/**
 * Template arguments are capitalized, just like class names.
 *
 * These are the preferred names for a few typical template
 * arguments:
 *  - Cont:        any STL-like container;
 *  - Iter:        any STL-like iterator;
 *  - FwdIter:     any STL-like forward iterator;
 *  - ResultType:  any type used to return a value;
 *  - T, T1, T2:   any type, generally used for values to be stored or passed.
 *
 * Also note that we use "class" to mean "pass me something that looks like
 * a class" and "typename" to mean "any type is welcome".
 */
template <class Cont, class FwdIter, typename SepType>
void split(Cont &out, FwdIter begin, FwdIter end, SepType sep);


/* Don't forget extra blank lines before EOF */