This document defines many guidelines that should be adhered to when developing 
against Banshee. These guidelines will make the codebase more readable,
extensible, and portable.

Commit Message Guidelines
=========================

Every change to source code must have a commit message associated to it. The
formatting details of this message are described here:

  http://live.gnome.org/Git/CommitMessages

Please review these guidelines separate to this document.


C# Coding Style Guidelines
==========================

These guidelines should be followed when writing code in Banshee. For the most
part they are similar to the Mono syntax guidelines [1]. All public API must
adhere to the .NET Framework Design Guidelines. [2]

Patches and additions to the code base will be checked for adherence to these
guidelines. If code is in violation, you will be asked to reformat it.

  1. Private variable/field names should be written like:

      lower_case_with_under_scores

  2. Property, event, and method names should be written like:

      UpperCaseStartingLetter

  3. A space before method/conditional parenthesis, braces:

      if (condition) {
         CallSomeFunction (args);
      }

  4. One space before a brace on the same line as a conditional or property:

      while (condition) {
         ...
      }

  5. Namespace, Class, Method braces on separate lines:

      namespace Foo
      {
          public class Bar
          {
              private void Method ()
              {
                  if (condition) {
                      ..
                  }
              }
          }
      }

  6. The exception to rule 5 is for Properties. The brace in the same line
     with the get/set keyword and the respective getter/setter block all
     inline, provided the block is simple:

      public string Something {
          get { return "yay"; }
      }

  7. If the property accessor block (get/set) is more than one line, use the
     alternative syntax:
     
      public string Something {
          set {
              DoSomething ();
              something = value;
          }
      }

  8. There is a space between generic parameters:

      Dictionary<K, V> not Dictionary<K,V>

  9. Use 4 space characters for indention, NOT tabs
   
  10. Try to observe a 120 character wrap margin. If your lines are over 120
     characters, break and indent them logically.


.NET API Naming Guidelines
==========================

  1. Member names should be descriptive and it is best to avoid abbreviations
     and acronyms

  2. If an abbreviation or acronym is used, it should be in the form of an 
     accepted name that is generally well known

  3. If an acronym is one-two characters long, it should be all caps 

      Banshee.IO and not Banshee.Io

  4. If an acronym is three or more characters long, only its first letter
     should be capitalized

      Banshee.Cdrom
      Banshee.Playlists.Formats.Pls
      Banshee.Playlists.Formats.M3u

  5. Prefix interfaces with 'I'

      IPlaylist
      IImportable


Implementation Guidelines
=========================

  1. Use generics and generic collections when possible in place of 
     1.0 features. New code in Banshee should leverage 2.0 features 
     as much as possible, and old code should be updated as development
     occurs in a given area.

      Use List<T> instead of ArrayList, Dictionary<K, V> instead of Hashtable

  2. In *most* cases Banshee.IO should be used (and possibly extended) when
     IO must be performed. Do *NOT* hard-code System.IO, Mono.Unix, or
     Gnome.Vfs IO into top-level APIs.

  3. When a platform-specific task needs to be performed, a top-level, 
     generic API must be designed first and then the platform implementation
     of the API can be added. See Banshee.Configuration for ideas.
   
  4. Do not hard code path separators. Use Path.DirectorySeparatorChar instead
     as it is portable to other platforms. 

  5. Try not to perform many string concatenations. Use a StringBuilder if
     necessary
   
  6. Avoid calls to Assembly.GetTypes as memory resulting from these calls
     will not be GCed.


Organization Guidelines
=======================

  1. Organize code into logical namespaces:

      Banshee.Cdrom
      Banshee.Cdrom.Gui
      Banshee.Cdrom.Nautilus

  2. Try to keep GUI as separate as possible from "real work" and keep
     the namespace separate as well, if possible and applicable. For instance,
     Many different CD-ROM backends could be written for different 
     platforms, but the same GUI should be used. Don't put GUI code in
     the platform implementation:

      Banshee.Cdrom
      Banshee.Cdrom.Gui
      Banshee.Cdrom.Nautilus

  3. Banshee's sources are layed out in the following way in the build:

     src/<high-level-group>/<assembly-name>/<namespace>/<class-or-interface>.cs

  4. Small member definitions (delegates, argument classes, enums) can go
     inside the same file containing the primary class, but classes should
     generally be in separate files. Use logical grouping with files.


[1] http://www.mono-project.com/Coding_Guidelines
[2] Highly recommended reading: http://www.amazon.com/gp/product/0321246756/ or
    view at: http://msdn2.microsoft.com/en-us/library/ms229042.aspx

