diff --git a/templates/settings.php b/templates/settings.php
deleted file mode 100644
index 3c562085cde198f82c676578a14cd3a028287011..0000000000000000000000000000000000000000
--- a/templates/settings.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<div class="wrap">
-    <h2>OpenTools Advanced Ordernumbers</h2>
-    <form method="post" action="options.php"> 
-        <?php @settings_fields('create_ordernumbers-group'); ?>
-        <?php @do_settings_fields('create_ordernumbers-group'); ?>
-
-        <table class="form-table">  
-            <tr valign="top">
-                <th scope="row"><label for="customize_ordernumbers">Customize Order Numbers</label></th>
-                <td><input type="text" name="customize_ordernumbers" id="customize_ordernumbers" value="<?php echo get_option('customize_ordernumbers'); ?>" /></td>
-            </tr>
-            <tr valign="top">
-                <th scope="row"><label for="ordernumber_format">Order Number Format</label></th>
-                <td><input type="text" name="ordernumber_format" id="ordernumber_format" value="<?php echo get_option('ordernumber_format'); ?>" /></td>
-            </tr>
-            <tr valign="top">
-                <th scope="row"><label for="ordernumber_counter_scope">Scope of the Counter</label></th>
-                <td><input type="text" name="ordernumber_counter_scope" id="ordernumber_counter_scope" value="<?php echo get_option('ordernumber_counter_scope'); ?>" /></td>
-            </tr>
-        </table>
-
-        <?php @submit_button(); ?>
-    </form>
-</div>
\ No newline at end of file
diff --git a/woocommerce-advanced-ordernumbers.php b/woocommerce-advanced-ordernumbers.php
index 1b80fd7379da6b7dac0c3f544321b4880fca1174..1b73efdff94ec5af93fb9fb40c6581cef1177f4f 100644
--- a/woocommerce-advanced-ordernumbers.php
+++ b/woocommerce-advanced-ordernumbers.php
@@ -37,85 +37,335 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 			public function __construct()
 			{
 				$plugin = plugin_basename(__FILE__); 
+
+
+				// Init settings
+				$this->settings = array(
+					array(
+						'name' 		=> __( 'Advanced Order Numbers', 'woocommerce-advanced-ordernumbers' ),
+						'desc'		=> __( 'Configure the format and the counters of the order numbers in WooCommerce.', 'woocommerce-advanced-ordernumbers' ),
+						'type' 		=> 'title',
+						'id' 		=> 'ordernumber_options'
+					),
+
+					array(
+						'name' 		=> __( 'Customize Order Numbers', 'woocommerce-advanced-ordernumbers' ),
+						'desc' 		=> __( 'Check to use custom order numbers rather than the default wordpress post ID.', 'woocommerce-advanced-ordernumbers' ),
+						'id' 		=> 'customize_ordernumber',
+						'type' 		=> 'checkbox',
+						'default'	=> 'no'
+					),
+					array(
+						'title'		=> __( 'Order number format', 'woocommerce-advanced-ordernumbers' ),
+						'desc' 		=> __( 'The format for the order numbers (variables can be entered as [...], the counter is indicated by the #). To use a different counter name than displayed, put the custom counter name after a |, e.g. "[year]-[month]/#|[year]" to use the month in the order number, but reset the counter only yearly.', 'woocommerce-advanced-ordernumbers' ),
+						'desc_tip'	=> true,
+						'id' 		=> 'ordernumber_format',
+						'default'	=> '#',
+						'type' 		=> 'text',
+					),
+					array(
+						'title'		=> __( 'Global', 'woocommerce-advanced-ordernumbers' ),
+						'desc' 		=> __( 'Counter Scope', 'woocommerce-advanced-ordernumbers' ),
+						'id' 		=> 'ordernumber_global',
+						'type' 		=> 'checkbox',
+						'default'	=> 'no'
+					),
+					array(
+						'title' 		=> __( 'Counter Digits', 'woocommerce-advanced-ordernumbers' ),
+						'desc' 		=> __( 'Minimum number of digits for the number', 'woocommerce-advanced-ordernumbers' ),
+						'desc_tip'	=> true,
+						'id' 		=> 'ordernumber_padding',
+						'type' 		=> 'number',
+						'default'	=> '0'
+					),
+					array(
+						'title' 	=> __( 'Counter Start', 'woocommerce-advanced-ordernumbers' ),
+						'desc' 		=> __( 'Start value for each new counter', 'woocommerce-advanced-ordernumbers' ),
+						'desc_tip'	=> true,
+						'id' 		=> 'ordernumber_start',
+						'type' 		=> 'number',
+						'default'	=> '1'
+					),
+					array(
+						'title'	=> __( 'Counter step', 'woocommerce-advanced-ordernumbers' ),
+						'desc' 		=> __( 'By how much the counter will be increased after each order. Typically 1.', 'woocommerce-advanced-ordernumbers' ),
+						'desc_tip'	=> true,
+						'id' 		=> 'ordernumber_step',
+						'type' 		=> 'number',
+						'default'	=> '1'
+					),
+					array( 'type' => 'sectionend', 'id' => 'ordernumber_options' ),
+					
+					// TODO: customize order password, and other numbers!
+				);
+				// Default options
+
+				add_option ('customize_ordernumber', '0');
+				add_option ('ordernumber_format',    "#");
+				add_option ('ordernumber_global',    '0');
+				add_option ('ordernumber_padding',   '1');
+				add_option ('ordernumber_start',     '1');
+				add_option ('ordernumber_step',      '1');
+
 				// register actions
-				add_action( 'admin_init', array(&$this, 'admin_init'));
-				add_action( 'admin_menu', array(&$this, 'add_menu'));
+// 				add_action( 'admin_init', array(&$this, 'admin_init'));
+// 				add_action( 'admin_menu', array(&$this, 'add_menu'));
+				// TODO: Find the proper action hooks to hook into:
+				add_filter( 'woocommerce_get_sections_checkout', array($this, 'add_admin_section'),1);
+// 				add_filter( 'woocommerce_get_settings_checkout', array( $this, 'admin_settings' ), 20, 2);
+				// The checkout page assumes all subpages are payment gateways, so we have to override this:
+				add_action( 'woocommerce_settings_checkout', array( $this, 'output' ) );
+				add_action( 'woocommerce_settings_save_checkout', array( $this, 'save' ) );
+				
+				add_action( 'woocommerce_update_options_catalog', array( $this, 'save_admin_settings' ) ); // < 2.1
+				add_action( 'woocommerce_update_options_products', array( $this, 'save_admin_settings' ) ); // 2.1 +
+
 				// register filters
 				add_filter("plugin_action_links_$plugin", array(&$this, 'plugin_settings_link'));
 				add_filter ('woocommerce_order_number', array(&$this, 'get_ordernumber'), 10, 2/*<= Also get the order object! */);
 			}
     
-			/**
-			* Activate the plugin
-			*/
-			public static function activate()
-			{
-				// Do nothing
-			}
+			// Activate the plugin
+			public static function activate() {}
     
-			/**
-			* Deactivate the plugin
-			*/     
-			public static function deactivate()
-			{
-				// Do nothing
+			// Deactivate the plugin
+			public static function deactivate() {}
+
+			function add_admin_section($sections) {
+				$sections['ordernumber'] = __( 'Order Numbers', 'woocommerce-advanced-ordernumbers');
+				return $sections;
+			}
+			
+			public function output() {
+				global $current_section;
+				if ($current_section == 'ordernumber') {
+					$settings = $this->settings;
+					WC_Admin_Settings::output_fields( $settings );
+				}
 			}
 
-			/**
-			 * hook into WP's admin_init action hook
-			 */
-			public function admin_init()
-			{
-				// Set up the settings for this plugin
-				$this->init_settings();
-				// Possibly do additional admin_init tasks
+			public function save() {
+				global $current_section;
+				if ($current_section == 'ordernumber') {
+					$settings = $this->settings;
+					WC_Admin_Settings::save_fields( $settings );
+				}
 			}
+
+// 			// Save the settings
+// 			function save_admin_settings() {
+// 				woocommerce_update_options( $this->settings );
+// 			}
+
+// 			/**
+// 			 * hook into WP's admin_init action hook
+// 			 */
+// 			public function admin_init()
+// 			{
+// 				// Set up the settings for this plugin
+// 				$this->init_settings();
+// 				// Possibly do additional admin_init tasks
+// 			}
+			
+// 			/**
+// 			* Initialize some custom settings
+// 			*/     
+// 			public function init_settings()
+// 			{
+// 				// register the settings for this plugin
+// 				// TODO: Properly design the set of options needed
+// 				register_setting('opentools-ordernumbers-group', 'customize_ordernumbers');
+// 				register_setting('opentools-ordernumbers-group', 'ordernumber_format');
+// 				register_setting('opentools-ordernumbers-group', 'ordernumber_counter_scope');
+// 			}
+			
+// 			/**
+// 			 * add a menu
+// 			 */     
+// 			public function add_menu()
+// 			{
+// 				// TODO: Move this inside the WooCommerce configuration!
+// 				add_options_page(
+// 					'Advanced Ordernumber Plugin Settings', // The title to be displayed in the browser window for this page.
+// 					'OpenTools Advanced Ordernumbers',      // The text to be displayed for this menu item 
+// 					'manage_options',                       // Which type of users can see this menu item
+// 					'opentools-ordernumbers',               // The unique ID - that is, the slug - for this menu item
+// 					array(&$this, 'plugin_settings_page')   // The name of the function to call when rendering this menu's page
+// 				);
+// 			}
+ 
+
+// 			function plugin_settings_link($links)
+// 			{ 
+// 				$settings_link = '<a href="options-general.php?page=opentools-ordernumbers">Settings</a>'; 
+// 				array_unshift($links, $settings_link); 
+// 				return $links; 
+// 			}
+
+// 			/**
+// 			 * Menu Callback
+// 			 */
+// 			public function plugin_settings_page()
+// 			{
+// 				if(!current_user_can('manage_options'))
+// 				{
+// 					wp_die(__('You do not have sufficient permissions to access this page.'));
+// 				}
+// 
+// 				// Render the settings template
+// 				include(sprintf("%s/templates/settings.php", dirname(__FILE__)));
+// 			}
+			
 			
 			/**
-			* Initialize some custom settings
-			*/     
-			public function init_settings()
-			{
-				// register the settings for this plugin
-				// TODO: Properly design the set of options needed
-				register_setting('opentools-ordernumbers-group', 'customize_ordernumbers');
-				register_setting('opentools-ordernumbers-group', 'ordernumber_format');
-				register_setting('opentools-ordernumbers-group', 'ordernumber_counter_scope');
+			 * Counter handling (simple loading/storing counters)
+			 */
+			function _getCounter($type, $format, $start=1) {
+				$count = get_option ('ordernumber-counter-'.$type.'-'.$format, $start);
+				return $count;
+			}
+			// Insert new counter value into the db or update existing one
+			function _setCounter($type, $format, $value) {
+				return update_option('ordernumber-counter-'.$type.'-'.$format, $value);
 			}
 			
+			
 			/**
-			 * add a menu
-			 */     
-			public function add_menu()
-			{
-				// TODO: Move this inside the WooCommerce configuration!
-				add_options_page('Advanced Ordernumber Plugin Settings', 'OpenTools Advanced Ordernumbers', 
-					'manage_options', 'opentools-ordernumbers', array(&$this, 'plugin_settings_page'));
-			} // END public function add_menu()
-
-			function plugin_settings_link($links)
-			{ 
-				$settings_link = '<a href="options-general.php?page=opentools-ordernumbers">Settings</a>'; 
-				array_unshift($links, $settings_link); 
-				return $links; 
+			 * Variable replacements:
+			 *   - Random strings/digits
+			 *   - Order properties
+			 *   - User properties
+			 */
+			
+			/* Return a random "string" of the given length taken from the given alphabet */
+			static function randomString($alphabet, $len) {
+				$alen = strlen($alphabet);
+				$r = "";
+				for ($n=0; $n<$len; $n++) {
+					$r .= $alphabet[mt_rand(0, $alen-1)];
+				}
+				return $r;
 			}
 
-			/**
-			 * Menu Callback
-			 */
-			public function plugin_settings_page()
-			{
-				if(!current_user_can('manage_options'))
-				{
-					wp_die(__('You do not have sufficient permissions to access this page.'));
+			function replaceRandom ($match) {
+				/* the regexp matches (random)(Type)(Len) as match, Type and Len is optional */
+				$len = ($match[3]?$match[3]:1);
+				// Fallback: If no Type is given, use Digit
+				$alphabet = "0123456789";
+				// Select the correct alphabet depending on Type
+				switch (strtolower($match[2])) {
+					case "digit": $alphabet = "0123456789"; break;
+					case "hex": $alphabet = "0123456789abcdef"; break;
+					case "letter": $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; break;
+					case "uletter": $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; break;
+					case "lletter": $alphabet = "abcdefghijklmnopqrstuvwxyz"; break;
+					case "alphanum": $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; break;
 				}
+				return self::randomString ($alphabet, $len);
+			}
+    
+			/* Extract the country information from the given ID */
+// 			static function getCountryFromID ($country_id) {
+// 				$db = JFactory::getDBO();
+// 				$query = 'SELECT * FROM `#__virtuemart_countries` WHERE `virtuemart_country_id` = ' . (int)$country_id;
+// 				$db->setQuery($query);
+// 				return $db->loadObject();
+// 			}
 
-				// Render the settings template
-				include(sprintf("%s/templates/settings.php", dirname(__FILE__)));
+
+
+			/* Type 0 means order number, type 1 means invoice number, type 2 means customer number, 3 means order password */
+			function replace_fields ($fmt, $type, $order) {
+				// First, replace all randomXXX[n] fields. This needs to be done with a regexp and a callback:
+				$fmt = preg_replace_callback ('/\[(random)(.*?)([0-9]*?)\]/', array($this, 'replaceRandom'), $fmt);
+        
+				$reps = array (
+					"[year]" => date ("Y"),
+					"[year2]" => date ("y"),
+					"[month]" => date("m"),
+					"[day]" => date("d"),
+					"[hour]" => date("H"),
+					"[hour12]" => date("h"),
+					"[ampm]" => date("a"),
+					"[minute]" => date("i"),
+					"[second]" => date("s"),
+					"[orderid]" => $order->id,
+					"[userid]" => $order->get_user_id(),
+				);
+// 				if (isset($order->virtuemart_vendor_id)) $reps["[vendorid]"] = $order->virtuemart_vendor_id;
+				$reps["[ipaddress]"]   = $order->customer_ip_address;
+				$reps["[orderstatus]"] = $order->get_status();
+				$reps["[email]"]       = $order->billing_email;
+        
+				
+				$reps["[firstname]"] = $order->billing_first_name;
+				$reps["[lastname]"] = $order->billing_last_name;
+
+				$reps["[company]"] = $order->billing_company;
+				$reps["[zip]"] = $order->billing_postcode;
+				$reps["[postcode]"] = $order->billing_postcode;
+				$reps["[city]"] = $order->billing_city;
+        
+				$country = $order->billing_country;
+				$state = $order->billing_state;
+				$allcountries = WC()->countries->get_countries();
+				$states = WC()->countries->get_states($country);
+				$reps["[country]"] = $country;
+				$reps["[countryname]"] = ( isset( $allcountries[ $country ] ) ) ? $allcountries[ $country ] : $country;
+
+				$reps["[state]"] = $state;
+				$reps["[statename]"] = ( $country && $state && isset( $states[ $country ][ $state ] ) ) ? $states[ $country ][ $state ] : $state;
+				
+				$reps["[articles]"] = $order->get_item_count();
+				$reps["[currency]"] = $order->get_order_currency();
+				$reps["[downloadpermitted]"] = $order->is_download_permitted();
+				$reps["[hasdownloads]"] = $order->has_downloadable_item();
+// 				$reps["[coupons]"] = $order->get_used_coupons();
+				
+				if ($type != 'ordernumber') {
+					$reps["[ordernumber]"] = $order->get_order_number();
+				}
+				$user = $order->get_user();
+				if ($user) {
+//					TODO: Shall we supply a variable for the user's login / display name?
+// 					$reps["[user]"] = print_r($user,1);
+// 					if (isset($order->username)) $reps["[username]"] = $order->username;
+				}
+				// Allow customization via plugins: filter function($reps, $order, $type, $fmt)
+				$reps = apply_filters( 'opentools_ordernumber_replacements', $reps, $order, $type, $fmt);
+// 				return print_r($reps,1);
+				return str_ireplace (array_keys($reps), array_values($reps), $fmt);
 			}
-			
-			
-			
+
+			function create_ordernumber($orderid, $order, $type='ordernumber') {
+				if (get_option('customize_'.$type, 'false')) {
+					$fmt     = get_option ($type.'_format',  "#");
+					$global  = get_option ($type.'_global',  1);
+					$padding = get_option ($type.'_padding', 1);
+					$step    = get_option ($type.'_step',    1);
+					$start   = get_option ($type.'_start',   1)-$step; // The counter contains the PREVIOUS number!
+
+					$nr = $this->replace_fields ($fmt, $type, $order);
+
+					// Split at a | to get the number format and a possibly different counter increment format
+					// If a separate counter format is given after the |, use it, otherwise reuse the number format itself as counter format
+					$parts = explode ("|", $nr);
+					$format = $parts[0];
+        
+					$counterfmt = ($global==1)?"":$parts[(count($parts)>1)?1:0];
+        
+					// Look up the current counter
+					$count = $this->_getCounter($type, $counterfmt, $start) + $step;
+					$this->_setCounter($type, $counterfmt, $count);
+					// return the format with the counter inserted
+					$number = str_replace ("#", sprintf('%0' . $padding . 's', $count), $format);
+					update_post_meta( $orderid, 'Order Number', $number );
+					return $number;
+				} else {
+					return $orderid;
+				}
+			}
+	
 			/** 
 			 * The hook to customize order numbers (requests the order number from the database; creates a new ordernumber if no entry exists in the database)
 			 */
@@ -123,19 +373,17 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 				$stored_number = get_post_meta( $orderid, 'Order Number', 'true');
 				if (!empty($stored_number)) {
 					return $stored_number;
-				} else {
+				} elseif (get_option('customize_ordernumber', 'false')) {
 					// create a new one (if this is a new order, otherwise we don't have/generate a number!)
-					$number = $this->create_ordernumber($orderid, $order);
-					update_post_meta( $orderid, 'Order Number', $number );
+					// TODO: Check whether this is a new number! Otherwise, do NOT create an order number
+					$number = $this->create_ordernumber($orderid, $order, 'ordernumber');
 					return $number;
+				} else {
+					print("<h1>Order number creation is DISABLED</h1>");
+					return $orderid;
 				}
 			}
 
-			function create_ordernumber($orderid, $order) {
-				$rnd=rand(100, 1000000);
-				return "Order-$orderid-Number-$rnd";
-			}
-	
 		}
 	}