← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 4186: Data entry: State (selected orgunit, dataset, period) is now managed on the client side. Periods ...

 

Merge authors:
  Lars Helge Øverland (larshelge)
------------------------------------------------------------
revno: 4186 [merge]
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2011-07-21 13:52:46 +0200
message:
  Data entry: State (selected orgunit, dataset, period) is now managed on the client side. Periods are generated on the client side. Impl a javascript library for period generation.
removed:
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDisplayModesAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadNextPreviousPeriodsAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadPeriodsAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/DefaultSelectedStateManager.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/SelectedStateManager.java
added:
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.date.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.glob.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/periodType.js
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetHistoryChartAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/HistoryAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDataSetsAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/PageInitAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/RegisterCompleteDataSetAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveCommentAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/UndoCompleteDataSetAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/history/DefaultHistoryRetriever.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/history.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/history.js
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java	2011-06-07 13:52:04 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java	2011-07-19 21:49:16 +0000
@@ -28,6 +28,8 @@
  */
 
 import java.io.Serializable;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
@@ -218,17 +220,62 @@
     }
 
     /**
+     * Parses a date from a String on the format YYYY-MM-DD.
+     * 
+     * @param dateString the String to parse.
+     * @return a Date based on the given String.
+     */
+    public static Date getMediumDate( String dateString )
+    {
+        try
+        {
+            final SimpleDateFormat format = new SimpleDateFormat();    
+            format.applyPattern( "yyyy-MM-dd" );    
+            return dateString != null ? format.parse( dateString ) : null;
+        }
+        catch ( ParseException ex )
+        {
+            throw new RuntimeException( "Failed to parse medium date", ex );
+        }
+    }
+    
+    /**
      * Returns an iso8601 formatted string representation of the period
      *
-     * @param period
+     * @param period the period.
      * @return the period as string
      */
     public abstract String getIsoDate( Period period );
 
+    /**
+     * Generates a period based on the given iso8601 formatted string.
+     * 
+     * @param isoDate the iso8601 string.
+     * @return the period.
+     */
     public abstract Period createPeriod( String isoDate );
 
     public abstract String getIsoFormat();
     
+    /**
+     * Creates a period based on the given external identifier, which is on the
+     * format [PeriodType]_[StartDate]. The start date is on the form yyyy-MM-dd.
+     * 
+     * @param externalId the external identifier.
+     * @return the period.
+     */
+    public static Period createPeriodExternalId( String externalId )
+    {
+        if ( externalId == null || externalId.split( "_" ).length <= 1 )
+        {
+            return null;
+        }
+        
+        final String[] id = externalId.split( "_" );
+        final PeriodType periodType = getPeriodTypeByName( id[0] );
+        return periodType.createPeriod( getMediumDate( id[1] ) );
+    }
+    
     // -------------------------------------------------------------------------
     // hashCode and equals
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java	2011-04-22 21:04:14 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java	2011-07-20 21:38:30 +0000
@@ -226,19 +226,19 @@
     {
         List<Period> periods = new ArrayList<Period>( historyLength );
 
+        lastPeriod = periodStore.reloadForceAddPeriod( lastPeriod );
+        
         CalendarPeriodType periodType = (CalendarPeriodType) lastPeriod.getPeriodType();
 
-        Period period = lastPeriod;
-
         Period p = new Period();
 
         for ( int i = 0; i < historyLength; ++i )
         {
-            p = getPeriodFromDates( period.getStartDate(), period.getEndDate(), periodType );
-
-            periods.add( p != null ? p : period );
-
-            period = periodType.getPreviousPeriod( period );
+            p = getPeriodFromDates( lastPeriod.getStartDate(), lastPeriod.getEndDate(), periodType );
+
+            periods.add( p != null ? p : lastPeriod );
+
+            lastPeriod = periodType.getPreviousPeriod( lastPeriod );
         }
 
         Collections.reverse( periods );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2011-07-18 07:54:57 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2011-07-19 06:11:23 +0000
@@ -1014,7 +1014,7 @@
           <ref local="org.hisp.dhis.dataset.DataSetShortNamePopulator" />
           <ref local="org.hisp.dhis.organisationunit.OrganisationUnitGroupSetPopulator" />
           <ref local="org.hisp.dhis.dataentryform.DataEntryFormPopulator" />
-		  <ref local="org.hisp.dhis.dataentryform.DataEntryFormUpgrader" />
+		  <!-- <ref local="org.hisp.dhis.dataentryform.DataEntryFormUpgrader" /> -->
         </list>
       </list>
     </property>

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java	2011-07-21 03:29:35 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java	2011-07-21 11:52:46 +0000
@@ -286,6 +286,8 @@
         DataElementCategoryOptionCombo categoryOptionCombo, Period lastPeriod, OrganisationUnit organisationUnit,
         int historyLength, I18nFormat format )
     {
+        lastPeriod = periodService.reloadPeriod( lastPeriod );
+        
         List<Period> periods = periodService.getPeriods( lastPeriod, historyLength );
 
         MinMaxDataElement minMax = minMaxDataElementService.getMinMaxDataElement( organisationUnit, dataElement,

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.date.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.date.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.date.js	2011-07-18 14:08:54 +0000
@@ -0,0 +1,135 @@
+/*
+ * jQuery Date
+ *
+ * Copyright 2010 Marc Grabanski
+ * Licensed under the MIT license
+ *
+ *
+ * Depends:
+ *	jquery.glob.js
+ */
+(function( $, undefined ) {
+
+if ( typeof( $.global.culture ) == "undefined" ) {
+	$.global.culture = $.global.cultures[ "default" ];
+}
+
+$.date = function ( datestring, formatstring ) {
+	var calendar = $.global.culture.calendar,
+		format = formatstring ? formatstring : calendar.patterns.d,
+		date = datestring ? $.global.parseDate(datestring, format) : new Date();
+	return {
+		refresh: function() {
+			calendar = $.global.culture.calendar;
+			format = formatstring || calendar.patterns.d;
+			return this;
+		},
+		setFormat: function( formatstring ) {
+			if ( formatstring ) {
+				format = formatstring;
+			}	
+			return this;
+		},
+		setDay: function( day ) {
+			date = new Date( date.getFullYear(), date.getMonth(), day );
+			return this;
+		},
+		adjust: function( period, offset ) {
+			var day = period == "D" ? date.getDate() + offset : date.getDate(), 
+				month = period == "M" ? date.getMonth() + offset : date.getMonth(), 
+				year = period == "Y" ? date.getFullYear() + offset : date.getFullYear();
+			date = new Date( year, month, day );
+			return this;
+		},
+		daysInMonth: function( year, month ) {
+			year = year || date.getFullYear();
+			month = month || date.getMonth();
+			return 32 - new Date( year, month, 32 ).getDate();
+		},
+		monthname: function() {
+			return calendar.months.names[ date.getMonth() ];
+		},
+		year: function() {
+			return date.getFullYear();
+		},
+		weekdays: function() {
+			// TODO take firstDay into account
+			var result = [];
+			for ( var dow = 0; dow < 7; dow++ ) {
+				var day = ( dow + calendar.firstDay ) % 7;
+				result.push( {
+					shortname: calendar.days.namesShort[ day ],
+					fullname: calendar.days.names[ day ],
+				});
+			}
+			return result;
+		},
+		days: function() {
+			var result = [],
+				firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(),
+				leadDays = ( firstDayOfMonth - calendar.firstDay + 7 ) % 7,
+				rows = Math.ceil( ( leadDays + this.daysInMonth() ) / 7),
+				printDate = new Date( this.year(), date.getMonth(), 1 - leadDays );
+			for ( var row = 0; row < rows; row++ ) {
+				var week = result[ result.length ] = {
+					number: this.iso8601Week( printDate ),
+					days: []
+				};
+				for ( var dayx = 0; dayx < 7; dayx++ ) {
+					var day = week.days[ week.days.length ] = {
+						lead: printDate.getMonth() != date.getMonth(),
+						date: printDate.getDate(),
+						current: this.selected && this.selected.equal( printDate ),
+						today: today.equal( printDate )
+					};
+					day.render = day.selectable = !day.lead;
+					this.eachDay( day );
+					// TODO use adjust("D", 1)?
+					printDate.setDate( printDate.getDate() + 1 );
+				}
+			}
+			return result;
+		},
+		iso8601Week: function( date ) {
+			var checkDate = new Date( date.getTime() );
+			// Find Thursday of this week starting on Monday
+			checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
+			var time = checkDate.getTime();
+			checkDate.setMonth( 0 ); // Compare with Jan 1
+			checkDate.setDate( 1 );
+			return Math.floor( Math.round( ( time - checkDate ) / 86400000) / 7 ) + 1;
+		},
+		select: function() {
+			this.selected = this.clone();
+			return this;
+		},
+		// TODO create new Date with year, month, day instead
+		clone: function() {
+			return $.date( this.format(), format );
+		},
+		// TODO compare year, month, day each for better performance
+		equal: function( other ) {
+			function format( date ) {
+				return $.global.format( date, "d" );
+			}
+			return format( date ) == format( other );
+		},
+		date: function() {
+			return date;
+		},
+		format: function( formatstring ) {
+			return $.global.format( date, formatstring ? formatstring : format );
+		},
+		calendar: function( newcalendar ) {
+			if ( newcalendar ) {
+				calendar = newcalendar;
+				return this;
+			}
+			return calendar;
+		}
+	}
+}
+
+var today = $.date();
+
+}( jQuery ));
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.glob.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.glob.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.glob.js	2011-07-18 14:08:54 +0000
@@ -0,0 +1,1342 @@
+/*!
+ * jQuery Globalization Plugin
+ * http://github.com/jquery/jquery-global
+ *
+ * Copyright Software Freedom Conservancy, Inc.
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ */
+(function() {
+
+var Globalization = {}, localized = { en: {} };
+localized["default"] = localized.en;
+
+Globalization.extend = function( deep ) {
+    var target = arguments[ 1 ] || {};
+    for ( var i = 2, l = arguments.length; i < l; i++ ) {
+        var source = arguments[ i ];
+        if ( source ) {
+            for ( var field in source ) {
+                var sourceVal = source[ field ];
+                if ( typeof sourceVal !== "undefined" ) {
+                    if ( deep && (isObject( sourceVal ) || isArray( sourceVal )) ) {
+                        var targetVal = target[ field ];
+                        // extend onto the existing value, or create a new one
+                        targetVal = targetVal && (isObject( targetVal ) || isArray( targetVal ))
+                            ? targetVal
+                            : (isArray( sourceVal ) ? [] : {});
+                        target[ field ] = this.extend( true, targetVal, sourceVal );
+                    }
+                    else {
+                        target[ field ] = sourceVal;
+                    }
+                }
+            }
+        }
+    }
+    return target;
+}
+
+Globalization.findClosestCulture = function(name) {
+    var match;
+    if ( !name ) {
+        return this.culture || this.cultures["default"];
+    }
+    if ( isString( name ) ) {
+        name = name.split( ',' );
+    }
+    if ( isArray( name ) ) {
+        var lang,
+            cultures = this.cultures,
+            list = name,
+            i, l = list.length,
+            prioritized = [];
+        for ( i = 0; i < l; i++ ) {
+            name = trim( list[ i ] );
+            var pri, parts = name.split( ';' );
+            lang = trim( parts[ 0 ] );
+            if ( parts.length === 1 ) {
+                pri = 1;
+            }
+            else {
+                name = trim( parts[ 1 ] );
+                if ( name.indexOf("q=") === 0 ) {
+                    name = name.substr( 2 );
+                    pri = parseFloat( name, 10 );
+                    pri = isNaN( pri ) ? 0 : pri;
+                }
+                else {
+                    pri = 1;
+                }
+            }
+            prioritized.push( { lang: lang, pri: pri } );
+        }
+        prioritized.sort(function(a, b) {
+            return a.pri < b.pri ? 1 : -1;
+        });
+        for ( i = 0; i < l; i++ ) {
+            lang = prioritized[ i ].lang;
+            match = cultures[ lang ];
+            // exact match?
+            if ( match ) {
+                return match;
+            }
+        }
+        for ( i = 0; i < l; i++ ) {
+            lang = prioritized[ i ].lang;
+            // for each entry try its neutral language
+            do {
+                var index = lang.lastIndexOf( "-" );
+                if ( index === -1 ) {
+                    break;
+                }
+                // strip off the last part. e.g. en-US => en
+                lang = lang.substr( 0, index );
+                match = cultures[ lang ];
+                if ( match ) {
+                    return match;
+                }
+            }
+            while ( 1 );
+        }
+    }
+    else if ( typeof name === 'object' ) {
+        return name;
+    }
+    return match || null;
+}
+Globalization.preferCulture = function(name) {
+    this.culture = this.findClosestCulture( name ) || this.cultures["default"];
+}
+Globalization.localize = function(key, culture, value) {
+    // usign default culture in case culture is not provided
+    if (typeof culture !== 'string') {
+        culture = this.culture.name || this.culture || "default";
+    }
+    culture = this.cultures[ culture ] || { name: culture };
+
+    var local = localized[ culture.name ];
+    if ( arguments.length === 3 ) {
+        if ( !local) {
+            local = localized[ culture.name ] = {};
+        }
+        local[ key ] = value;
+    }
+    else {
+        if ( local ) {
+            value = local[ key ];
+        }
+        if ( typeof value === 'undefined' ) {
+            var language = localized[ culture.language ];
+            if ( language ) {
+                value = language[ key ];
+            }
+            if ( typeof value === 'undefined' ) {
+                value = localized["default"][ key ];
+            }
+        }
+    }
+    return typeof value === "undefined" ? null : value;
+}
+Globalization.format = function(value, format, culture) {
+    culture = this.findClosestCulture( culture );
+    if ( typeof value === "number" ) {
+        value = formatNumber( value, format, culture );
+    }
+    else if ( value instanceof Date ) {
+        value = formatDate( value, format, culture );
+    }
+    return value;
+}
+Globalization.parseInt = function(value, radix, culture) {
+    return Math.floor( this.parseFloat( value, radix, culture ) );
+}
+Globalization.parseFloat = function(value, radix, culture) {
+	// make radix optional
+	if (typeof radix === "string") {
+		culture = radix;
+		radix = 10;
+	}
+	
+    culture = this.findClosestCulture( culture );
+    var ret = NaN,
+        nf = culture.numberFormat;
+
+	if (value.indexOf(culture.numberFormat.currency.symbol) > -1) {
+		// remove currency symbol
+		value = value.replace(culture.numberFormat.currency.symbol, "");
+		// replace decimal seperator
+		value = value.replace(culture.numberFormat.currency["."], culture.numberFormat["."]);
+	}
+
+    // trim leading and trailing whitespace
+    value = trim( value );
+
+    // allow infinity or hexidecimal
+    if (regexInfinity.test(value)) {
+        ret = parseFloat(value, radix);
+    }
+    else if (!radix && regexHex.test(value)) {
+        ret = parseInt(value, 16);
+    }
+    else {
+        var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ),
+            sign = signInfo[0],
+            num = signInfo[1];
+        // determine sign and number
+        if ( sign === "" && nf.pattern[0] !== "-n" ) {
+            signInfo = parseNegativePattern( value, nf, "-n" );
+            sign = signInfo[0];
+            num = signInfo[1];
+        }
+        sign = sign || "+";
+        // determine exponent and number
+        var exponent,
+            intAndFraction,
+            exponentPos = num.indexOf( 'e' );
+        if ( exponentPos < 0 ) exponentPos = num.indexOf( 'E' );
+        if ( exponentPos < 0 ) {
+            intAndFraction = num;
+            exponent = null;
+        }
+        else {
+            intAndFraction = num.substr( 0, exponentPos );
+            exponent = num.substr( exponentPos + 1 );
+        }
+        // determine decimal position
+        var integer,
+            fraction,
+            decSep = nf['.'],
+            decimalPos = intAndFraction.indexOf( decSep );
+        if ( decimalPos < 0 ) {
+            integer = intAndFraction;
+            fraction = null;
+        }
+        else {
+            integer = intAndFraction.substr( 0, decimalPos );
+            fraction = intAndFraction.substr( decimalPos + decSep.length );
+        }
+        // handle groups (e.g. 1,000,000)
+        var groupSep = nf[","];
+        integer = integer.split(groupSep).join('');
+        var altGroupSep = groupSep.replace(/\u00A0/g, " ");
+        if ( groupSep !== altGroupSep ) {
+            integer = integer.split(altGroupSep).join('');
+        }
+        // build a natively parsable number string
+        var p = sign + integer;
+        if ( fraction !== null ) {
+            p += '.' + fraction;
+        }
+        if ( exponent !== null ) {
+            // exponent itself may have a number patternd
+            var expSignInfo = parseNegativePattern( exponent, nf, "-n" );
+            p += 'e' + (expSignInfo[0] || "+") + expSignInfo[1];
+        }
+        if ( regexParseFloat.test( p ) ) {
+            ret = parseFloat( p );
+        }
+    }
+    return ret;
+}
+Globalization.parseDate = function(value, formats, culture) {
+    culture = this.findClosestCulture( culture );
+
+    var date, prop, patterns;
+    if ( formats ) {
+        if ( typeof formats === "string" ) {
+            formats = [ formats ];
+        }
+        if ( formats.length ) {
+            for ( var i = 0, l = formats.length; i < l; i++ ) {
+                var format = formats[ i ];
+                if ( format ) {
+                    date = parseExact( value, format, culture );
+                    if ( date ) {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    else {
+        patterns = culture.calendar.patterns;
+        for ( prop in patterns ) {
+            date = parseExact( value, patterns[prop], culture );
+            if ( date ) {
+                break;
+            }
+        }
+    }
+    return date || null;
+}
+
+// 1.    When defining a culture, all fields are required except the ones stated as optional.
+// 2.    You can use Globalization.extend to copy an existing culture and provide only the differing values,
+//       a good practice since most cultures do not differ too much from the 'default' culture.
+//       DO use the 'default' culture if you do this, as it is the only one that definitely
+//       exists.
+// 3.    Other plugins may add to the culture information provided by extending it. However,
+//       that plugin may extend it prior to the culture being defined, or after. Therefore,
+//       do not overwrite values that already exist when defining the baseline for a culture,
+//       by extending your culture object with the existing one.
+// 4.    Each culture should have a ".calendars" object with at least one calendar named "standard"
+//       which serves as the default calendar in use by that culture.
+// 5.    Each culture should have a ".calendar" object which is the current calendar being used,
+//       it may be dynamically changed at any time to one of the calendars in ".calendars".
+
+// To define a culture, use the following pattern, which handles defining the culture based
+// on the 'default culture, extending it with the existing culture if it exists, and defining
+// it if it does not exist.
+// Globalization.cultures.foo = Globalization.extend(true, Globalization.extend(true, {}, Globalization.cultures['default'], fooCulture), Globalization.cultures.foo)
+
+var cultures = Globalization.cultures = Globalization.cultures || {};
+var en = cultures["default"] = cultures.en = Globalization.extend(true, {
+    // A unique name for the culture in the form <language code>-<country/region code>
+    name: "en",
+    // the name of the culture in the english language
+    englishName: "English",
+    // the name of the culture in its own language
+    nativeName: "English",
+    // whether the culture uses right-to-left text
+    isRTL: false,
+    // 'language' is used for so-called "specific" cultures.
+    // For example, the culture "es-CL" means "Spanish, in Chili".
+    // It represents the Spanish-speaking culture as it is in Chili,
+    // which might have different formatting rules or even translations
+    // than Spanish in Spain. A "neutral" culture is one that is not
+    // specific to a region. For example, the culture "es" is the generic
+    // Spanish culture, which may be a more generalized version of the language
+    // that may or may not be what a specific culture expects.
+    // For a specific culture like "es-CL", the 'language' field refers to the
+    // neutral, generic culture information for the language it is using.
+    // This is not always a simple matter of the string before the dash.
+    // For example, the "zh-Hans" culture is netural (Simplified Chinese).
+    // And the 'zh-SG' culture is Simplified Chinese in Singapore, whose lanugage
+    // field is "zh-CHS", not "zh".
+    // This field should be used to navigate from a specific culture to it's
+    // more general, neutral culture. If a culture is already as general as it
+    // can get, the language may refer to itself.
+    language: "en",
+    // numberFormat defines general number formatting rules, like the digits in
+    // each grouping, the group separator, and how negative numbers are displayed.
+    numberFormat: {
+        // [negativePattern]
+        // Note, numberFormat.pattern has no 'positivePattern' unlike percent and currency,
+        // but is still defined as an array for consistency with them.
+        //  negativePattern: one of "(n)|-n|- n|n-|n -"
+        pattern: ["-n"],
+        // number of decimal places normally shown
+        decimals: 2,
+        // string that separates number groups, as in 1,000,000
+        ',': ",",
+        // string that separates a number from the fractional portion, as in 1.99
+        '.': ".",
+        // array of numbers indicating the size of each number group.
+        // TODO: more detailed description and example
+        groupSizes: [3],
+        // symbol used for positive numbers
+        '+': "+",
+        // symbol used for negative numbers
+        '-': "-",
+        percent: {
+            // [negativePattern, positivePattern]
+            //     negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %"
+            //     positivePattern: one of "n %|n%|%n|% n"
+            pattern: ["-n %","n %"],
+            // number of decimal places normally shown
+            decimals: 2,
+            // array of numbers indicating the size of each number group.
+            // TODO: more detailed description and example
+            groupSizes: [3],
+            // string that separates number groups, as in 1,000,000
+            ',': ",",
+            // string that separates a number from the fractional portion, as in 1.99
+            '.': ".",
+            // symbol used to represent a percentage
+            symbol: "%"
+        },
+        currency: {
+            // [negativePattern, positivePattern]
+            //     negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)"
+            //     positivePattern: one of "$n|n$|$ n|n $"
+            pattern: ["($n)","$n"],
+            // number of decimal places normally shown
+            decimals: 2,
+            // array of numbers indicating the size of each number group.
+            // TODO: more detailed description and example
+            groupSizes: [3],
+            // string that separates number groups, as in 1,000,000
+            ',': ",",
+            // string that separates a number from the fractional portion, as in 1.99
+            '.': ".",
+            // symbol used to represent currency
+            symbol: "$"
+        }
+    },
+    // calendars defines all the possible calendars used by this culture.
+    // There should be at least one defined with name 'standard', and is the default
+    // calendar used by the culture.
+    // A calendar contains information about how dates are formatted, information about
+    // the calendar's eras, a standard set of the date formats,
+    // translations for day and month names, and if the calendar is not based on the Gregorian
+    // calendar, conversion functions to and from the Gregorian calendar.
+    calendars: {
+        standard: {
+            // name that identifies the type of calendar this is
+            name: "Gregorian_USEnglish",
+            // separator of parts of a date (e.g. '/' in 11/05/1955)
+            '/': "/",
+            // separator of parts of a time (e.g. ':' in 05:44 PM)
+            ':': ":",
+            // the first day of the week (0 = Sunday, 1 = Monday, etc)
+            firstDay: 0,
+            days: {
+                // full day names
+                names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
+                // abbreviated day names
+                namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
+                // shortest day names
+                namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"]
+            },
+            months: {
+                // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar)
+                names: ["January","February","March","April","May","June","July","August","September","October","November","December",""],
+                // abbreviated month names
+                namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""]
+            },
+            // AM and PM designators in one of these forms:
+            // The usual view, and the upper and lower case versions
+            //      [standard,lowercase,uppercase]
+            // The culture does not use AM or PM (likely all standard date formats use 24 hour time)
+            //      null
+            AM: ["AM", "am", "AM"],
+            PM: ["PM", "pm", "PM"],
+            eras: [
+                // eras in reverse chronological order.
+                // name: the name of the era in this culture (e.g. A.D., C.E.)
+                // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era.
+                // offset: offset in years from gregorian calendar
+                { "name": "A.D.", "start": null, "offset": 0 }
+            ],
+            // when a two digit year is given, it will never be parsed as a four digit
+            // year greater than this year (in the appropriate era for the culture)
+            // Set it as a full year (e.g. 2029) or use an offset format starting from
+            // the current year: "+19" would correspond to 2029 if the current year 2010.
+            twoDigitYearMax: 2029,
+            // set of predefined date and time patterns used by the culture
+            // these represent the format someone in this culture would expect
+            // to see given the portions of the date that are shown.
+            patterns: {
+                // short date pattern
+                d: "M/d/yyyy",
+                // long date pattern
+                D: "dddd, MMMM dd, yyyy",
+                // short time pattern
+                t: "h:mm tt",
+                // long time pattern
+                T: "h:mm:ss tt",
+                // long date, short time pattern
+                f: "dddd, MMMM dd, yyyy h:mm tt",
+                // long date, long time pattern
+                F: "dddd, MMMM dd, yyyy h:mm:ss tt",
+                // month/day pattern
+                M: "MMMM dd",
+                // month/year pattern
+                Y: "yyyy MMMM",
+                // S is a sortable format that does not vary by culture
+                S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss"
+            }
+            // optional fields for each calendar:
+            /*
+            monthsGenitive:
+                Same as months but used when the day preceeds the month.
+                Omit if the culture has no genitive distinction in month names.
+                For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx
+            convert:
+                Allows for the support of non-gregorian based calendars. This convert object is used to
+                to convert a date to and from a gregorian calendar date to handle parsing and formatting.
+                The two functions:
+                    fromGregorian(date)
+                        Given the date as a parameter, return an array with parts [year, month, day]
+                        corresponding to the non-gregorian based year, month, and day for the calendar.
+                    toGregorian(year, month, day)
+                        Given the non-gregorian year, month, and day, return a new Date() object
+                        set to the corresponding date in the gregorian calendar.
+            */
+        }
+    }
+}, cultures.en);
+en.calendar = en.calendar || en.calendars.standard;
+
+var regexTrim = /^\s+|\s+$/g,
+    regexInfinity = /^[+-]?infinity$/i,
+    regexHex = /^0x[a-f0-9]+$/i,
+    regexParseFloat = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/,
+    toString = Object.prototype.toString;
+
+function startsWith(value, pattern) {
+    return value.indexOf( pattern ) === 0;
+}
+
+function endsWith(value, pattern) {
+    return value.substr( value.length - pattern.length ) === pattern;
+}
+
+function trim(value) {
+    return (value+"").replace( regexTrim, "" );
+}
+
+function zeroPad(str, count, left) {
+    for (var l=str.length; l < count; l++) {
+        str = (left ? ('0' + str) : (str + '0'));
+    }
+    return str;
+}
+
+function isArray(obj) {
+    return toString.call(obj) === "[object Array]";
+}
+
+function isString(obj) {
+    return toString.call(obj) === "[object String]";
+}
+
+function isObject(obj) {
+    return toString.call(obj) === "[object Object]";
+}
+
+function arrayIndexOf( array, item ) {
+    if ( array.indexOf ) {
+        return array.indexOf( item );
+    }
+    for ( var i = 0, length = array.length; i < length; i++ ) {
+        if ( array[ i ] === item ) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+// *************************************** Numbers ***************************************
+
+function expandNumber(number, precision, formatInfo) {
+    var groupSizes = formatInfo.groupSizes,
+        curSize = groupSizes[ 0 ],
+        curGroupIndex = 1,
+        factor = Math.pow( 10, precision ),
+        rounded = Math.round( number * factor ) / factor;
+    if ( !isFinite(rounded) ) {
+        rounded = number;
+    }
+    number = rounded;
+
+    var numberString = number+"",
+        right = "",
+        split = numberString.split(/e/i),
+        exponent = split.length > 1 ? parseInt( split[ 1 ], 10 ) : 0;
+    numberString = split[ 0 ];
+    split = numberString.split( "." );
+    numberString = split[ 0 ];
+    right = split.length > 1 ? split[ 1 ] : "";
+
+    var l;
+    if ( exponent > 0 ) {
+        right = zeroPad( right, exponent, false );
+        numberString += right.slice( 0, exponent );
+        right = right.substr( exponent );
+    }
+    else if ( exponent < 0 ) {
+        exponent = -exponent;
+        numberString = zeroPad( numberString, exponent + 1 );
+        right = numberString.slice( -exponent, numberString.length ) + right;
+        numberString = numberString.slice( 0, -exponent );
+    }
+
+    if ( precision > 0 ) {
+        right = formatInfo['.'] +
+            ((right.length > precision) ? right.slice( 0, precision ) : zeroPad( right, precision ));
+    }
+    else {
+        right = "";
+    }
+
+    var stringIndex = numberString.length - 1,
+        sep = formatInfo[","],
+        ret = "";
+
+    while ( stringIndex >= 0 ) {
+        if ( curSize === 0 || curSize > stringIndex ) {
+            return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? ( sep + ret + right ) : right );
+        }
+        ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? ( sep + ret ) : "" );
+
+        stringIndex -= curSize;
+
+        if ( curGroupIndex < groupSizes.length ) {
+            curSize = groupSizes[ curGroupIndex ];
+            curGroupIndex++;
+        }
+    }
+    return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right;
+}
+
+
+function parseNegativePattern(value, nf, negativePattern) {
+    var neg = nf["-"],
+        pos = nf["+"],
+        ret;
+    switch (negativePattern) {
+        case "n -":
+            neg = ' ' + neg;
+            pos = ' ' + pos;
+            // fall through
+        case "n-":
+            if ( endsWith( value, neg ) ) {
+                ret = [ '-', value.substr( 0, value.length - neg.length ) ];
+            }
+            else if ( endsWith( value, pos ) ) {
+                ret = [ '+', value.substr( 0, value.length - pos.length ) ];
+            }
+            break;
+        case "- n":
+            neg += ' ';
+            pos += ' ';
+            // fall through
+        case "-n":
+            if ( startsWith( value, neg ) ) {
+                ret = [ '-', value.substr( neg.length ) ];
+            }
+            else if ( startsWith(value, pos) ) {
+                ret = [ '+', value.substr( pos.length ) ];
+            }
+            break;
+        case "(n)":
+            if ( startsWith( value, '(' ) && endsWith( value, ')' ) ) {
+                ret = [ '-', value.substr( 1, value.length - 2 ) ];
+            }
+            break;
+    }
+    return ret || [ '', value ];
+}
+
+function formatNumber(value, format, culture) {
+    if ( !format || format === 'i' ) {
+        return culture.name.length ? value.toLocaleString() : value.toString();
+    }
+    format = format || "D";
+
+    var nf = culture.numberFormat,
+        number = Math.abs(value),
+        precision = -1,
+        pattern;
+    if (format.length > 1) precision = parseInt( format.slice( 1 ), 10 );
+
+    var current = format.charAt( 0 ).toUpperCase(),
+        formatInfo;
+
+    switch (current) {
+        case "D":
+            pattern = 'n';
+            if (precision !== -1) {
+                number = zeroPad( ""+number, precision, true );
+            }
+            if (value < 0) number = -number;
+            break;
+        case "N":
+            formatInfo = nf;
+            // fall through
+        case "C":
+            formatInfo = formatInfo || nf.currency;
+            // fall through
+        case "P":
+            formatInfo = formatInfo || nf.percent;
+            pattern = value < 0 ? formatInfo.pattern[0] : (formatInfo.pattern[1] || "n");
+            if (precision === -1) precision = formatInfo.decimals;
+            number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo );
+            break;
+        default:
+            throw "Bad number format specifier: " + current;
+    }
+
+    var patternParts = /n|\$|-|%/g,
+        ret = "";
+    for (;;) {
+        var index = patternParts.lastIndex,
+            ar = patternParts.exec(pattern);
+
+        ret += pattern.slice( index, ar ? ar.index : pattern.length );
+
+        if (!ar) {
+            break;
+        }
+
+        switch (ar[0]) {
+            case "n":
+                ret += number;
+                break;
+            case "$":
+                ret += nf.currency.symbol;
+                break;
+            case "-":
+                // don't make 0 negative
+                if ( /[1-9]/.test( number ) ) {
+                    ret += nf["-"];
+                }
+                break;
+            case "%":
+                ret += nf.percent.symbol;
+                break;
+        }
+    }
+
+    return ret;
+}
+
+// *************************************** Dates ***************************************
+
+function outOfRange(value, low, high) {
+    return value < low || value > high;
+}
+
+function expandYear(cal, year) {
+    // expands 2-digit year into 4 digits.
+    var now = new Date(),
+        era = getEra(now);
+    if ( year < 100 ) {
+        var twoDigitYearMax = cal.twoDigitYearMax;
+        twoDigitYearMax = typeof twoDigitYearMax === 'string' ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax;
+        var curr = getEraYear( now, cal, era );
+        year += curr - ( curr % 100 );
+        if ( year > twoDigitYearMax ) {
+            year -= 100;
+        }
+    }
+    return year;
+}
+
+function getEra(date, eras) {
+    if ( !eras ) return 0;
+    var start, ticks = date.getTime();
+    for ( var i = 0, l = eras.length; i < l; i++ ) {
+        start = eras[ i ].start;
+        if ( start === null || ticks >= start ) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+function toUpper(value) {
+    // 'he-IL' has non-breaking space in weekday names.
+    return value.split( "\u00A0" ).join(' ').toUpperCase();
+}
+
+function toUpperArray(arr) {
+    var results = [];
+    for ( var i = 0, l = arr.length; i < l; i++ ) {
+        results[i] = toUpper(arr[i]);
+    }
+    return results;
+}
+
+function getEraYear(date, cal, era, sortable) {
+    var year = date.getFullYear();
+    if ( !sortable && cal.eras ) {
+        // convert normal gregorian year to era-shifted gregorian
+        // year by subtracting the era offset
+        year -= cal.eras[ era ].offset;
+    }
+    return year;
+}
+
+function getDayIndex(cal, value, abbr) {
+    var ret,
+        days = cal.days,
+        upperDays = cal._upperDays;
+    if ( !upperDays ) {
+        cal._upperDays = upperDays = [
+            toUpperArray( days.names ),
+            toUpperArray( days.namesAbbr ),
+            toUpperArray( days.namesShort )
+        ];
+    }
+    value = toUpper( value );
+    if ( abbr ) {
+        ret = arrayIndexOf( upperDays[ 1 ], value );
+        if ( ret === -1 ) {
+            ret = arrayIndexOf( upperDays[ 2 ], value );
+        }
+    }
+    else {
+        ret = arrayIndexOf( upperDays[ 0 ], value );
+    }
+    return ret;
+}
+
+function getMonthIndex(cal, value, abbr) {
+    var months = cal.months,
+        monthsGen = cal.monthsGenitive || cal.months,
+        upperMonths = cal._upperMonths,
+        upperMonthsGen = cal._upperMonthsGen;
+    if ( !upperMonths ) {
+        cal._upperMonths = upperMonths = [
+            toUpperArray( months.names ),
+            toUpperArray( months.namesAbbr )
+        ];
+        cal._upperMonthsGen = upperMonthsGen = [
+            toUpperArray( monthsGen.names ),
+            toUpperArray( monthsGen.namesAbbr )
+        ];
+    }
+    value = toUpper( value );
+    var i = arrayIndexOf( abbr ? upperMonths[ 1 ] : upperMonths[ 0 ], value );
+    if ( i < 0 ) {
+        i = arrayIndexOf( abbr ? upperMonthsGen[ 1 ] : upperMonthsGen[ 0 ], value );
+    }
+    return i;
+}
+
+function appendPreOrPostMatch(preMatch, strings) {
+    // appends pre- and post- token match strings while removing escaped characters.
+    // Returns a single quote count which is used to determine if the token occurs
+    // in a string literal.
+    var quoteCount = 0,
+        escaped = false;
+    for ( var i = 0, il = preMatch.length; i < il; i++ ) {
+        var c = preMatch.charAt( i );
+        switch ( c ) {
+            case '\'':
+                if ( escaped ) {
+                    strings.push( "'" );
+                }
+                else {
+                    quoteCount++;
+                }
+                escaped = false;
+                break;
+            case '\\':
+                if ( escaped ) {
+                    strings.push( "\\" );
+                }
+                escaped = !escaped;
+                break;
+            default:
+                strings.push( c );
+                escaped = false;
+                break;
+        }
+    }
+    return quoteCount;
+}
+
+function expandFormat(cal, format) {
+    // expands unspecified or single character date formats into the full pattern.
+    format = format || "F";
+    var pattern,
+        patterns = cal.patterns,
+        len = format.length;
+    if ( len === 1 ) {
+        pattern = patterns[ format ];
+        if ( !pattern ) {
+            throw "Invalid date format string '" + format + "'.";
+        }
+        format = pattern;
+    }
+    else if ( len === 2  && format.charAt(0) === "%" ) {
+        // %X escape format -- intended as a custom format string that is only one character, not a built-in format.
+        format = format.charAt( 1 );
+    }
+    return format;
+}
+
+function getParseRegExp(cal, format) {
+    // converts a format string into a regular expression with groups that
+    // can be used to extract date fields from a date string.
+    // check for a cached parse regex.
+    var re = cal._parseRegExp;
+    if ( !re ) {
+        cal._parseRegExp = re = {};
+    }
+    else {
+        var reFormat = re[ format ];
+        if ( reFormat ) {
+            return reFormat;
+        }
+    }
+
+    // expand single digit formats, then escape regular expression characters.
+    var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ),
+        regexp = ["^"],
+        groups = [],
+        index = 0,
+        quoteCount = 0,
+        tokenRegExp = getTokenRegExp(),
+        match;
+
+    // iterate through each date token found.
+    while ( (match = tokenRegExp.exec( expFormat )) !== null ) {
+        var preMatch = expFormat.slice( index, match.index );
+        index = tokenRegExp.lastIndex;
+
+        // don't replace any matches that occur inside a string literal.
+        quoteCount += appendPreOrPostMatch( preMatch, regexp );
+        if ( quoteCount % 2 ) {
+            regexp.push( match[ 0 ] );
+            continue;
+        }
+
+        // add a regex group for the token.
+        var m = match[ 0 ],
+            len = m.length,
+            add;
+        switch ( m ) {
+            case 'dddd': case 'ddd':
+            case 'MMMM': case 'MMM':
+            case 'gg': case 'g':
+                add = "(\\D+)";
+                break;
+            case 'tt': case 't':
+                add = "(\\D*)";
+                break;
+            case 'yyyy':
+            case 'fff':
+            case 'ff':
+            case 'f':
+                add = "(\\d{" + len + "})";
+                break;
+            case 'dd': case 'd':
+            case 'MM': case 'M':
+            case 'yy': case 'y':
+            case 'HH': case 'H':
+            case 'hh': case 'h':
+            case 'mm': case 'm':
+            case 'ss': case 's':
+                add = "(\\d\\d?)";
+                break;
+            case 'zzz':
+                add = "([+-]?\\d\\d?:\\d{2})";
+                break;
+            case 'zz': case 'z':
+                add = "([+-]?\\d\\d?)";
+                break;
+            case '/':
+                add = "(\\" + cal["/"] + ")";
+                break;
+            default:
+                throw "Invalid date format pattern '" + m + "'.";
+                break;
+        }
+        if ( add ) {
+            regexp.push( add );
+        }
+        groups.push( match[ 0 ] );
+    }
+    appendPreOrPostMatch( expFormat.slice( index ), regexp );
+    regexp.push( "$" );
+
+    // allow whitespace to differ when matching formats.
+    var regexpStr = regexp.join( '' ).replace( /\s+/g, "\\s+" ),
+        parseRegExp = {'regExp': regexpStr, 'groups': groups};
+
+    // cache the regex for this format.
+    return re[ format ] = parseRegExp;
+}
+
+function getTokenRegExp() {
+    // regular expression for matching date and time tokens in format strings.
+    return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g;
+}
+
+function parseExact(value, format, culture) {
+    // try to parse the date string by matching against the format string
+    // while using the specified culture for date field names.
+    value = trim( value );
+    var cal = culture.calendar,
+        // convert date formats into regular expressions with groupings.
+        // use the regexp to determine the input format and extract the date fields.
+        parseInfo = getParseRegExp(cal, format),
+        match = new RegExp(parseInfo.regExp).exec(value);
+    if (match === null) {
+        return null;
+    }
+    // found a date format that matches the input.
+    var groups = parseInfo.groups,
+        era = null, year = null, month = null, date = null, weekDay = null,
+        hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null,
+        pmHour = false;
+    // iterate the format groups to extract and set the date fields.
+    for ( var j = 0, jl = groups.length; j < jl; j++ ) {
+        var matchGroup = match[ j + 1 ];
+        if ( matchGroup ) {
+            var current = groups[ j ],
+                clength = current.length,
+                matchInt = parseInt( matchGroup, 10 );
+            switch ( current ) {
+                case 'dd': case 'd':
+                    // Day of month.
+                    date = matchInt;
+                    // check that date is generally in valid range, also checking overflow below.
+                    if ( outOfRange( date, 1, 31 ) ) return null;
+                    break;
+                case 'MMM':
+                case 'MMMM':
+                    month = getMonthIndex( cal, matchGroup, clength === 3 );
+                    if ( outOfRange( month, 0, 11 ) ) return null;
+                    break;
+                case 'M': case 'MM':
+                    // Month.
+                    month = matchInt - 1;
+                    if ( outOfRange( month, 0, 11 ) ) return null;
+                    break;
+                case 'y': case 'yy':
+                case 'yyyy':
+                    year = clength < 4 ? expandYear( cal, matchInt ) : matchInt;
+                    if ( outOfRange( year, 0, 9999 ) ) return null;
+                    break;
+                case 'h': case 'hh':
+                    // Hours (12-hour clock).
+                    hour = matchInt;
+                    if ( hour === 12 ) hour = 0;
+                    if ( outOfRange( hour, 0, 11 ) ) return null;
+                    break;
+                case 'H': case 'HH':
+                    // Hours (24-hour clock).
+                    hour = matchInt;
+                    if ( outOfRange( hour, 0, 23 ) ) return null;
+                    break;
+                case 'm': case 'mm':
+                    // Minutes.
+                    min = matchInt;
+                    if ( outOfRange( min, 0, 59 ) ) return null;
+                    break;
+                case 's': case 'ss':
+                    // Seconds.
+                    sec = matchInt;
+                    if ( outOfRange( sec, 0, 59 ) ) return null;
+                    break;
+                case 'tt': case 't':
+                    // AM/PM designator.
+                    // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of
+                    // the AM tokens. If not, fail the parse for this format.
+                    pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] );
+                    if ( !pmHour && ( !cal.AM || (matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2]) ) ) return null;
+                    break;
+                case 'f':
+                    // Deciseconds.
+                case 'ff':
+                    // Centiseconds.
+                case 'fff':
+                    // Milliseconds.
+                    msec = matchInt * Math.pow( 10, 3-clength );
+                    if ( outOfRange( msec, 0, 999 ) ) return null;
+                    break;
+                case 'ddd':
+                    // Day of week.
+                case 'dddd':
+                    // Day of week.
+                    weekDay = getDayIndex( cal, matchGroup, clength === 3 );
+                    if ( outOfRange( weekDay, 0, 6 ) ) return null;
+                    break;
+                case 'zzz':
+                    // Time zone offset in +/- hours:min.
+                    var offsets = matchGroup.split( /:/ );
+                    if ( offsets.length !== 2 ) return null;
+                    hourOffset = parseInt( offsets[ 0 ], 10 );
+                    if ( outOfRange( hourOffset, -12, 13 ) ) return null;
+                    var minOffset = parseInt( offsets[ 1 ], 10 );
+                    if ( outOfRange( minOffset, 0, 59 ) ) return null;
+                    tzMinOffset = (hourOffset * 60) + (startsWith( matchGroup, '-' ) ? -minOffset : minOffset);
+                    break;
+                case 'z': case 'zz':
+                    // Time zone offset in +/- hours.
+                    hourOffset = matchInt;
+                    if ( outOfRange( hourOffset, -12, 13 ) ) return null;
+                    tzMinOffset = hourOffset * 60;
+                    break;
+                case 'g': case 'gg':
+                    var eraName = matchGroup;
+                    if ( !eraName || !cal.eras ) return null;
+                    eraName = trim( eraName.toLowerCase() );
+                    for ( var i = 0, l = cal.eras.length; i < l; i++ ) {
+                        if ( eraName === cal.eras[ i ].name.toLowerCase() ) {
+                            era = i;
+                            break;
+                        }
+                    }
+                    // could not find an era with that name
+                    if ( era === null ) return null;
+                    break;
+            }
+        }
+    }
+    var result = new Date(), defaultYear, convert = cal.convert;
+    defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear();
+    if ( year === null ) {
+        year = defaultYear;
+    }
+    else if ( cal.eras ) {
+        // year must be shifted to normal gregorian year
+        // but not if year was not specified, its already normal gregorian
+        // per the main if clause above.
+        year += cal.eras[ (era || 0) ].offset;
+    }
+    // set default day and month to 1 and January, so if unspecified, these are the defaults
+    // instead of the current day/month.
+    if ( month === null ) {
+        month = 0;
+    }
+    if ( date === null ) {
+        date = 1;
+    }
+    // now have year, month, and date, but in the culture's calendar.
+    // convert to gregorian if necessary
+    if ( convert ) {
+        result = convert.toGregorian( year, month, date );
+        // conversion failed, must be an invalid match
+        if ( result === null ) return null;
+    }
+    else {
+        // have to set year, month and date together to avoid overflow based on current date.
+        result.setFullYear( year, month, date );
+        // check to see if date overflowed for specified month (only checked 1-31 above).
+        if ( result.getDate() !== date ) return null;
+        // invalid day of week.
+        if ( weekDay !== null && result.getDay() !== weekDay ) {
+            return null;
+        }
+    }
+    // if pm designator token was found make sure the hours fit the 24-hour clock.
+    if ( pmHour && hour < 12 ) {
+        hour += 12;
+    }
+    result.setHours( hour, min, sec, msec );
+    if ( tzMinOffset !== null ) {
+        // adjust timezone to utc before applying local offset.
+        var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() );
+        // Safari limits hours and minutes to the range of -127 to 127.  We need to use setHours
+        // to ensure both these fields will not exceed this range.  adjustedMin will range
+        // somewhere between -1440 and 1500, so we only need to split this into hours.
+        result.setHours( result.getHours() + parseInt( adjustedMin / 60, 10 ), adjustedMin % 60 );
+    }
+    return result;
+}
+
+function formatDate(value, format, culture) {
+    var cal = culture.calendar,
+        convert = cal.convert;
+    if ( !format || !format.length || format === 'i' ) {
+        var ret;
+        if ( culture && culture.name.length ) {
+            if ( convert ) {
+                // non-gregorian calendar, so we cannot use built-in toLocaleString()
+                ret = formatDate( value, cal.patterns.F, culture );
+            }
+            else {
+                var eraDate = new Date( value.getTime() ),
+                    era = getEra( value, cal.eras );
+                eraDate.setFullYear( getEraYear( value, cal, era ) );
+                ret = eraDate.toLocaleString();
+            }
+        }
+        else {
+            ret = value.toString();
+        }
+        return ret;
+    }
+
+    var eras = cal.eras,
+        sortable = format === "s";
+    format = expandFormat( cal, format );
+
+    // Start with an empty string
+    ret = [];
+    var hour,
+        zeros = ['0','00','000'],
+        foundDay,
+        checkedDay,
+        dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g,
+        quoteCount = 0,
+        tokenRegExp = getTokenRegExp(),
+        converted;
+
+    function padZeros(num, c) {
+        var r, s = num+'';
+        if ( c > 1 && s.length < c ) {
+            r = ( zeros[ c - 2 ] + s);
+            return r.substr( r.length - c, c );
+        }
+        else {
+            r = s;
+        }
+        return r;
+    }
+
+    function hasDay() {
+        if ( foundDay || checkedDay ) {
+            return foundDay;
+        }
+        foundDay = dayPartRegExp.test( format );
+        checkedDay = true;
+        return foundDay;
+    }
+
+    function getPart( date, part ) {
+        if ( converted ) {
+            return converted[ part ];
+        }
+        switch ( part ) {
+            case 0: return date.getFullYear();
+            case 1: return date.getMonth();
+            case 2: return date.getDate();
+        }
+    }
+
+    if ( !sortable && convert ) {
+        converted = convert.fromGregorian( value );
+    }
+
+    for (;;) {
+        // Save the current index
+        var index = tokenRegExp.lastIndex,
+            // Look for the next pattern
+            ar = tokenRegExp.exec( format );
+
+        // Append the text before the pattern (or the end of the string if not found)
+        var preMatch = format.slice( index, ar ? ar.index : format.length );
+        quoteCount += appendPreOrPostMatch( preMatch, ret );
+
+        if ( !ar ) {
+            break;
+        }
+
+        // do not replace any matches that occur inside a string literal.
+        if ( quoteCount % 2 ) {
+            ret.push( ar[ 0 ] );
+            continue;
+        }
+
+        var current = ar[ 0 ],
+            clength = current.length;
+
+        switch ( current ) {
+            case "ddd":
+                //Day of the week, as a three-letter abbreviation
+            case "dddd":
+                // Day of the week, using the full name
+                names = (clength === 3) ? cal.days.namesAbbr : cal.days.names;
+                ret.push( names[ value.getDay() ] );
+                break;
+            case "d":
+                // Day of month, without leading zero for single-digit days
+            case "dd":
+                // Day of month, with leading zero for single-digit days
+                foundDay = true;
+                ret.push( padZeros( getPart( value, 2 ), clength ) );
+                break;
+            case "MMM":
+                // Month, as a three-letter abbreviation
+            case "MMMM":
+                // Month, using the full name
+                var part = getPart( value, 1 );
+                ret.push( (cal.monthsGenitive && hasDay())
+                    ? cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ]
+                    : cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ] );
+                break;
+            case "M":
+                // Month, as digits, with no leading zero for single-digit months
+            case "MM":
+                // Month, as digits, with leading zero for single-digit months
+                ret.push( padZeros( getPart( value, 1 ) + 1, clength ) );
+                break;
+            case "y":
+                // Year, as two digits, but with no leading zero for years less than 10
+            case "yy":
+                // Year, as two digits, with leading zero for years less than 10
+            case "yyyy":
+                // Year represented by four full digits
+                part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra( value, eras ), sortable );
+                if ( clength < 4 ) {
+                    part = part % 100;
+                }
+                ret.push( padZeros( part, clength ) );
+                break;
+            case "h":
+                // Hours with no leading zero for single-digit hours, using 12-hour clock
+            case "hh":
+                // Hours with leading zero for single-digit hours, using 12-hour clock
+                hour = value.getHours() % 12;
+                if ( hour === 0 ) hour = 12;
+                ret.push( padZeros( hour, clength ) );
+                break;
+            case "H":
+                // Hours with no leading zero for single-digit hours, using 24-hour clock
+            case "HH":
+                // Hours with leading zero for single-digit hours, using 24-hour clock
+                ret.push( padZeros( value.getHours(), clength ) );
+                break;
+            case "m":
+                // Minutes with no leading zero  for single-digit minutes
+            case "mm":
+                // Minutes with leading zero  for single-digit minutes
+                ret.push( padZeros( value.getMinutes(), clength ) );
+                break;
+            case "s":
+                // Seconds with no leading zero for single-digit seconds
+            case "ss":
+                // Seconds with leading zero for single-digit seconds
+                ret.push( padZeros(value .getSeconds(), clength ) );
+                break;
+            case "t":
+                // One character am/pm indicator ("a" or "p")
+            case "tt":
+                // Multicharacter am/pm indicator
+                part = value.getHours() < 12 ? (cal.AM ? cal.AM[0] : " ") : (cal.PM ? cal.PM[0] : " ");
+                ret.push( clength === 1 ? part.charAt( 0 ) : part );
+                break;
+            case "f":
+                // Deciseconds
+            case "ff":
+                // Centiseconds
+            case "fff":
+                // Milliseconds
+                ret.push( padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) );
+                break;
+            case "z":
+                // Time zone offset, no leading zero
+            case "zz":
+                // Time zone offset with leading zero
+                hour = value.getTimezoneOffset() / 60;
+                ret.push( (hour <= 0 ? '+' : '-') + padZeros( Math.floor( Math.abs( hour ) ), clength ) );
+                break;
+            case "zzz":
+                // Time zone offset with leading zero
+                hour = value.getTimezoneOffset() / 60;
+                ret.push( (hour <= 0 ? '+' : '-') + padZeros( Math.floor( Math.abs( hour ) ), 2 ) +
+                    // Hard coded ":" separator, rather than using cal.TimeSeparator
+                    // Repeated here for consistency, plus ":" was already assumed in date parsing.
+                    ":" + padZeros( Math.abs( value.getTimezoneOffset() % 60 ), 2 ) );
+                break;
+            case "g":
+            case "gg":
+                if ( cal.eras ) {
+                    ret.push( cal.eras[ getEra(value, eras) ].name );
+                }
+                break;
+        case "/":
+            ret.push( cal["/"] );
+            break;
+        default:
+            throw "Invalid date format pattern '" + current + "'.";
+            break;
+        }
+    }
+    return ret.join( '' );
+}
+
+// EXPORTS
+jQuery.global = Globalization;
+
+})();
+
+

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/periodType.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/periodType.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/periodType.js	2011-07-21 11:52:46 +0000
@@ -0,0 +1,216 @@
+
+function PeriodType()
+{
+	var dateFormat = 'yyyy-MM-dd';
+	
+	var periodTypes = [];
+	periodTypes['Daily'] = new DailyPeriodType( dateFormat );
+	periodTypes['Weekly'] = new WeeklyPeriodType( dateFormat );
+	periodTypes['Monthly'] = new MonthlyPeriodType( dateFormat );
+	periodTypes['Quarterly'] = new QuarterlyPeriodType( dateFormat );
+	periodTypes['SixMonthly'] = new SixMonthlyPeriodType( dateFormat );
+	periodTypes['Yearly'] = new YearlyPeriodType( dateFormat );
+	
+	this.get = function( key )
+	{
+		return periodTypes[key];
+	}
+	
+	this.reverse = function( array )
+	{
+		var reversed = [];		
+		var i = 0;
+		
+		for ( var j = array.length - 1; j >= 0; j-- )
+		{
+			reversed[i++] = array[j];
+		}
+		
+		return reversed;
+	}
+	
+	this.filterFuturePeriods = function( periods )
+	{
+		var array = [];
+		var i = 0;
+		
+		var now = new Date().getTime();
+		
+		for ( var j = 0; j < periods.length; j++ )
+		{
+			var c = periods[j];
+			var d = periods[j]['startDate'];
+			var e = null;
+			
+			if ( $.date( periods[j]['startDate'], dateFormat ).date().getTime() < now )
+			{
+				array[i++] = periods[j];
+			}			
+		}
+		
+		return array;
+	}
+}
+
+function DailyPeriodType( dateFormat )
+{
+	this.generatePeriods = function( offset )
+	{
+		var periods = [];
+		var year = new Date().getFullYear() + offset;
+		var startDate = $.date( year + '-01-01', dateFormat );		
+		var i = 0;
+		
+		while ( startDate.date().getFullYear() <= year )
+		{
+			var period = [];
+			period['startDate'] = startDate.format( dateFormat );
+			period['name'] = startDate.format( dateFormat );
+			period['id'] = 'Daily_' + period['startDate'];
+			periods[i]= period;
+			
+			startDate.adjust( 'D', +1 );
+			i++;
+		}
+		
+		return periods;
+	}
+}
+
+function WeeklyPeriodType( dateFormat )
+{
+	this.generatePeriods = function( offset )
+	{
+		var periods = [];
+		var year = new Date().getFullYear() + offset;
+		var startDate = $.date( year + '-01-01', dateFormat );	
+		var day = startDate.date().getDay();
+		var i = 0;
+		
+		if ( day == 0 ) // Sunday, forward to Monday
+		{
+			startDate.adjust( 'D', +1 );
+		}
+		else if ( day <= 4 ) // Monday - Thursday, rewind to Monday
+		{
+			startDate.adjust( 'D', ( ( day - 1 ) * -1 ) );
+		}
+		else // Friday - Saturday, forward to Monday
+		{
+			startDate.adjust( 'D', ( 8 - day ) );
+		}		
+		
+		while ( startDate.date().getFullYear() <= year )
+		{
+			var period = [];
+			period['startDate'] = startDate.format( dateFormat );
+			period['name'] = 'W' + ( i + 1 ) + ' - ' + startDate.format( dateFormat );
+			period['id'] = 'Weekly_' + period['startDate'];
+			periods[i] = period;
+			
+			startDate.adjust( 'D', +7 );
+			i++;
+		}
+		
+		return periods;
+	}
+}
+
+function MonthlyPeriodType( dateFormat )
+{
+	this.generatePeriods = function( offset )
+	{
+		var periods = [];
+		var year = new Date().getFullYear() + offset;
+		var startDate = $.date( year + '-01-01', dateFormat );		
+		var i = 0;
+				
+		while ( startDate.date().getFullYear() == year )
+		{
+			var period = [];
+			period['startDate'] = startDate.format( dateFormat );
+			period['name'] = monthNames[i] + ' ' + year;
+			period['id'] = 'Monthly_' + period['startDate'];
+			periods[i] = period;
+			
+			startDate.adjust( 'M', +1 );
+			i++;
+		}
+		
+		return periods;
+	}
+}
+
+function QuarterlyPeriodType( dateFormat )
+{
+	this.generatePeriods = function( offset )
+	{
+		var periods = [];
+		var year = new Date().getFullYear() + offset;
+		var startDate = $.date( year + '-01-01', dateFormat );
+		var i = 0;
+		var j = 0;
+		
+		while ( startDate.date().getFullYear() == year )
+		{
+			var period = [];
+			period['startDate'] = startDate.format( dateFormat );
+			period['name'] = monthNames[i] + ' - ' + monthNames[i+2] + ' ' + year;
+			period['id'] = 'Quarterly_' + period['startDate'];
+			periods[j] = period;
+			
+			startDate.adjust( 'M', +3 );
+			i += 3;
+			j++;
+		}
+		
+		return periods;
+	}
+}
+
+function SixMonthlyPeriodType( dateFormat )
+{
+	this.generatePeriods = function( offset )
+	{
+		var periods = [];
+		var year = new Date().getFullYear() + offset;
+		
+		var period = [];
+		period['startDate'] = year + '-01-01';
+		period['name'] = monthNames[0] + ' - ' + monthNames[5] + ' ' + year;
+		period['id'] = 'SixMonthly_' + period['startDate'];
+		periods[0] = period;
+		
+		period = [];
+		period['startDate'] = year + '-06-01';
+		period['name'] = monthNames[6] + ' - ' + monthNames[11] + ' ' + year;
+		period['id'] = 'SixMonthly_' + period['startDate'];
+		periods[1] = period;
+		
+		return periods;
+	}	
+}
+
+function YearlyPeriodType( dateFormat )
+{	
+	this.generatePeriods = function( offset )
+	{
+		var periods = [];
+		var year = new Date().getFullYear() + offset;
+		var startDate = $.date( year + '-01-01', dateFormat ).adjust( 'Y', -5 );
+		var i = 0;
+		
+		for ( var i = 0; i < 11; i++ )
+		{
+			var period = [];
+			period['startDate'] = startDate.format( dateFormat );
+			period['name'] = startDate.date().getFullYear();			
+			period['id'] = 'Yearly_' + period['startDate'];
+			periods[i] = period;
+			
+			startDate.adjust( 'Y', +1 );
+		}
+		
+		return periods;
+	}		
+}

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm	2011-06-16 08:08:02 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm	2011-07-21 11:52:46 +0000
@@ -34,11 +34,14 @@
 	<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/jquery.validate.js"></script>
 	<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/jquery.validate.ext.js"></script>
 	<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/jquery.cookie.js"></script>
+	<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/jquery.glob.js"></script>
+	<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/jquery.date.js"></script>
 	<script type="text/javascript" src="../dhis-web-commons/javascripts/jQuery/jquery.tmpl.js"></script>
 	<script type="text/javascript" src="../dhis-web-commons/i18nJavaScriptSupport.action"></script>
     <script type="text/javascript" src="../dhis-web-commons/javascripts/commons.js"></script>
     <script type="text/javascript" src="../dhis-web-commons/javascripts/commons.ajax.js"></script>
     <script type="text/javascript" src="../dhis-web-commons/javascripts/lists.js"></script>
+    <script type="text/javascript" src="../dhis-web-commons/javascripts/periodType.js"></script>
     <script type="text/javascript" src="../dhis-web-commons/javascripts/date.js"></script>
     <script type="text/javascript" src="../dhis-web-commons/javascripts/validationRules.js"></script>
 

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java	2011-07-13 15:09:37 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java	2011-07-19 21:49:16 +0000
@@ -30,13 +30,15 @@
 import java.util.Collection;
 
 import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.datavalue.DataValue;
 import org.hisp.dhis.datavalue.DataValueService;
-import org.hisp.dhis.de.state.SelectedStateManager;
 import org.hisp.dhis.minmax.MinMaxDataElement;
 import org.hisp.dhis.minmax.MinMaxDataElementService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodType;
 
 import com.opensymphony.xwork2.Action;
 
@@ -64,24 +66,38 @@
         this.minMaxDataElementService = minMaxDataElementService;
     }
 
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
+    private DataSetService dataSetService;
+    
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
+
+    private OrganisationUnitSelectionManager selectionManager;
+
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
+    {
+        this.selectionManager = selectionManager;
     }
 
     // -------------------------------------------------------------------------
     // Input
     // -------------------------------------------------------------------------
 
-    private Integer selectedPeriodIndex;
-
-    public void setSelectedPeriodIndex( Integer selectedPeriodIndex )
-    {
-        this.selectedPeriodIndex = selectedPeriodIndex;
-    }
-
+    private String periodId;
+
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
+    
+    private Integer dataSetId;
+
+    public void setDataSetId( Integer dataSetId )
+    {
+        this.dataSetId = dataSetId;
+    }
+    
     // -------------------------------------------------------------------------
     // Output
     // -------------------------------------------------------------------------
@@ -106,14 +122,9 @@
 
     public String execute()
     {
-        if ( selectedPeriodIndex != null )
-        {
-            selectedStateManager.setSelectedPeriodIndex( selectedPeriodIndex );
-        }
-        
-        Period period = selectedStateManager.getSelectedPeriod();
-        DataSet dataSet = selectedStateManager.getSelectedDataSet();
-        OrganisationUnit unit = selectedStateManager.getSelectedOrganisationUnit();
+        Period period = PeriodType.createPeriodExternalId( periodId );
+        DataSet dataSet = dataSetService.getDataSet( dataSetId );
+        OrganisationUnit unit = selectionManager.getSelectedOrganisationUnit();
         
         dataValues = dataValueService.getDataValues( unit, period, dataSet.getDataElements() );
         

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetHistoryChartAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetHistoryChartAction.java	2010-04-12 21:23:33 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetHistoryChartAction.java	2011-07-20 21:38:30 +0000
@@ -32,10 +32,11 @@
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dataelement.DataElementCategoryService;
 import org.hisp.dhis.dataelement.DataElementService;
-import org.hisp.dhis.de.state.SelectedStateManager;
 import org.hisp.dhis.i18n.I18nFormat;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodType;
 import org.jfree.chart.JFreeChart;
 
 import com.opensymphony.xwork2.Action;
@@ -73,13 +74,13 @@
         this.categoryService = categoryService;
     }
 
-    private SelectedStateManager selectedStateManager;
+    private OrganisationUnitSelectionManager selectionManager;
 
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
     {
-        this.selectedStateManager = selectedStateManager;
+        this.selectionManager = selectionManager;
     }
-    
+
     private I18nFormat format;
 
     public void setFormat( I18nFormat format )
@@ -105,6 +106,12 @@
         this.categoryOptionComboId = categoryOptionComboId;
     }
 
+    private String periodId;
+
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
 
     // -------------------------------------------------------------------------
     // Output
@@ -140,8 +147,9 @@
         DataElement dataElement = dataElementService.getDataElement( dataElementId );
         DataElementCategoryOptionCombo categoryOptionCombo = categoryService.getDataElementCategoryOptionCombo( categoryOptionComboId );
 
-        Period period = selectedStateManager.getSelectedPeriod();
-        OrganisationUnit organisationUnit = selectedStateManager.getSelectedOrganisationUnit();
+        Period period = PeriodType.createPeriodExternalId( periodId );
+        
+        OrganisationUnit organisationUnit = selectionManager.getSelectedOrganisationUnit();
         
         chart = chartService.getJFreeChartHistory( dataElement, categoryOptionCombo, period, organisationUnit, HISTORY_LENGTH, format );
         

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/HistoryAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/HistoryAction.java	2011-06-27 10:39:01 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/HistoryAction.java	2011-07-20 21:38:30 +0000
@@ -40,9 +40,10 @@
 import org.hisp.dhis.datavalue.DataValueService;
 import org.hisp.dhis.de.history.DataElementHistory;
 import org.hisp.dhis.de.history.HistoryRetriever;
-import org.hisp.dhis.de.state.SelectedStateManager;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodType;
 
 import com.opensymphony.xwork2.Action;
 
@@ -86,13 +87,6 @@
     {
         this.categoryService = categoryService;
     }
-
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
     
     private DataValueAuditService dataValueAuditService;
 
@@ -100,7 +94,14 @@
     {
         this.dataValueAuditService = dataValueAuditService;
     }
-    
+
+    private OrganisationUnitSelectionManager selectionManager;
+
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
+    {
+        this.selectionManager = selectionManager;
+    }
+
     // -------------------------------------------------------------------------
     // Input
     // -------------------------------------------------------------------------
@@ -131,6 +132,18 @@
     	return showComment;
     }
 
+    private String periodId;
+
+    public String getPeriodId()
+    {
+        return periodId;
+    }
+
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
+
     // -------------------------------------------------------------------------
     // Output
     // -------------------------------------------------------------------------
@@ -191,9 +204,9 @@
             throw new Exception( "DataElement doesn't exist: " + dataElementId );
         }
 
-        Period period = selectedStateManager.getSelectedPeriod();
+        Period period = PeriodType.createPeriodExternalId( periodId );
 
-        OrganisationUnit organisationUnit = selectedStateManager.getSelectedOrganisationUnit();
+        OrganisationUnit organisationUnit = selectionManager.getSelectedOrganisationUnit();
         
         dataValue = dataValueService.getDataValue( organisationUnit, dataElement, period, optionCombo );
 

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDataSetsAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDataSetsAction.java	2011-05-20 13:28:27 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDataSetsAction.java	2011-07-19 21:49:16 +0000
@@ -30,12 +30,17 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 
 import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.dataset.comparator.DataSetNameComparator;
-import org.hisp.dhis.de.state.SelectedStateManager;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
+import org.hisp.dhis.period.CalendarPeriodType;
+import org.hisp.dhis.user.CurrentUserService;
+import org.hisp.dhis.user.User;
 
 import com.opensymphony.xwork2.Action;
 
@@ -49,13 +54,38 @@
     // Dependencies
     // -------------------------------------------------------------------------
 
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
-
+    private OrganisationUnitSelectionManager selectionManager;
+
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
+    {
+        this.selectionManager = selectionManager;
+    }
+
+    private CurrentUserService currentUserService;
+
+    public void setCurrentUserService( CurrentUserService currentUserService )
+    {
+        this.currentUserService = currentUserService;
+    }
+
+    private DataSetService dataSetService;
+
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
+    
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private Integer dataSetId;
+
+    public void setDataSetId( Integer dataSetId )
+    {
+        this.dataSetId = dataSetId;
+    }
+    
     // -------------------------------------------------------------------------
     // Output
     // -------------------------------------------------------------------------
@@ -94,7 +124,7 @@
 
     public String execute()
     {
-        organisationUnit = selectedStateManager.getSelectedOrganisationUnit();
+        organisationUnit = selectionManager.getSelectedOrganisationUnit();
 
         if ( organisationUnit != null )
         {        
@@ -102,7 +132,7 @@
             // Load data sets for selected org unit
             // -----------------------------------------------------------------
 
-            dataSets = selectedStateManager.loadDataSetsForSelectedOrgUnit();
+            dataSets = loadDataSetsForSelectedOrgUnit( organisationUnit );
     
             Collections.sort( dataSets, new DataSetNameComparator() );
 
@@ -110,21 +140,51 @@
             // Check if selected data set is associated with selected org unit
             // -----------------------------------------------------------------
 
-            DataSet selectedDataSet = selectedStateManager.getSelectedDataSet();
-            
-            if ( selectedDataSet != null && dataSets.contains( selectedDataSet ) )
+            if ( dataSetId != null )
             {
-                dataSetValid = true;
+                DataSet selectedDataSet = dataSetService.getDataSet( dataSetId );
                 
-                periodValid = selectedStateManager.getSelectedPeriod() != null;
-            }
-            else
-            {
-                selectedStateManager.clearSelectedDataSet();
-                selectedStateManager.clearSelectedPeriod();
+                if ( selectedDataSet != null && dataSets.contains( selectedDataSet ) )
+                {
+                    dataSetValid = true;
+                }
             }
         }
         
         return SUCCESS;
     }
+    
+    private List<DataSet> loadDataSetsForSelectedOrgUnit( OrganisationUnit organisationUnit )
+    {
+        List<DataSet> dataSets = new ArrayList<DataSet>( organisationUnit.getDataSets() );
+
+        // ---------------------------------------------------------------------
+        // Retain only DataSets from current user's authority groups
+        // ---------------------------------------------------------------------
+
+        User currentUser = currentUserService.getCurrentUser();
+        
+        if ( currentUser != null && !currentUserService.currentUserIsSuper() )
+        {
+            dataSets.retainAll( currentUser.getUserCredentials().getAllDataSets() );
+        }
+
+        // ---------------------------------------------------------------------
+        // Remove DataSets which don't have a CalendarPeriodType
+        // ---------------------------------------------------------------------
+
+        Iterator<DataSet> iterator = dataSets.iterator();
+
+        while ( iterator.hasNext() )
+        {
+            DataSet dataSet = iterator.next();
+
+            if ( !( dataSet.getPeriodType() instanceof CalendarPeriodType) )
+            {
+                iterator.remove();
+            }
+        }
+
+        return dataSets;
+    }
 }

=== removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDisplayModesAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDisplayModesAction.java	2011-05-20 13:28:27 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDisplayModesAction.java	1970-01-01 00:00:00 +0000
@@ -1,94 +0,0 @@
-package org.hisp.dhis.de.action;
-
-/*
- * Copyright (c) 2004-2010, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- *   be used to endorse or promote products derived from this software without
- *   specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import org.hisp.dhis.dataset.DataSet;
-import org.hisp.dhis.de.state.SelectedStateManager;
-
-import com.opensymphony.xwork2.Action;
-
-/**
- * @author Lars Helge Overland
- */
-public class LoadDisplayModesAction
-    implements Action
-{
-    // -------------------------------------------------------------------------
-    // Dependencies
-    // -------------------------------------------------------------------------
-
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
-
-    // -------------------------------------------------------------------------
-    // Output
-    // -------------------------------------------------------------------------
-
-    private boolean customForm;
-    
-    public boolean isCustomForm()
-    {
-        return customForm;
-    }
-
-    private boolean sectionForm;
-
-    public boolean isSectionForm()
-    {
-        return sectionForm;
-    }
-    
-    private String displayMode;
-
-    public String getDisplayMode()
-    {
-        return displayMode;
-    }
-
-    // -------------------------------------------------------------------------
-    // Action implementation
-    // -------------------------------------------------------------------------
-
-    @Override
-    public String execute()
-    {
-        DataSet dataSet = selectedStateManager.getSelectedDataSet();
-        
-        customForm = dataSet.hasDataEntryForm();
-
-        sectionForm = dataSet.hasSections();
-
-        displayMode = selectedStateManager.getSelectedDisplayMode();
-        
-        return SUCCESS;
-    }
-}

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java	2011-07-14 06:29:58 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java	2011-07-21 11:52:46 +0000
@@ -54,14 +54,15 @@
 import org.hisp.dhis.dataset.CompleteDataSetRegistration;
 import org.hisp.dhis.dataset.CompleteDataSetRegistrationService;
 import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.dataset.Section;
 import org.hisp.dhis.dataset.comparator.SectionOrderComparator;
-import org.hisp.dhis.datavalue.DataValue;
-import org.hisp.dhis.de.state.SelectedStateManager;
 import org.hisp.dhis.i18n.I18n;
 import org.hisp.dhis.options.displayproperty.DisplayPropertyHandler;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodType;
 
 import com.opensymphony.xwork2.Action;
 
@@ -74,8 +75,6 @@
 {
     private static final Log log = LogFactory.getLog( LoadFormAction.class );
 
-    private static final String SECTION_FORM = "sectionform";
-    
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
@@ -93,6 +92,13 @@
     {
         this.dataElementService = dataElementService;
     }
+    
+    private DataSetService dataSetService;
+
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
 
     private DataSetLockService dataSetLockService;
 
@@ -101,11 +107,11 @@
         this.dataSetLockService = dataSetLockService;
     }
 
-    private SelectedStateManager selectedStateManager;
+    private OrganisationUnitSelectionManager selectionManager;
 
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
     {
-        this.selectedStateManager = selectedStateManager;
+        this.selectionManager = selectionManager;
     }
 
     private CompleteDataSetRegistrationService registrationService;
@@ -169,13 +175,6 @@
         return this.customDataEntryFormCode;
     }
 
-    private String displayMode;
-
-    public void setDisplayMode( String displayMode )
-    {
-        this.displayMode = displayMode;
-    }
-
     private OrganisationUnit organisationUnit;
 
     public OrganisationUnit getOrganisationUnit()
@@ -218,42 +217,25 @@
         return sections;
     }
 
-    private Map<String, DataValue> dataValueMap;
-
-    public Map<String, DataValue> getDataValueMap()
-    {
-        return dataValueMap;
-    }
-
-    private List<String> standardComments;
-
-    public List<String> getStandardComments()
-    {
-        return standardComments;
-    }
-
-    private Integer selectedDataSetId;
-
-    public void setSelectedDataSetId( Integer selectedDataSetId )
-    {
-        this.selectedDataSetId = selectedDataSetId;
-    }
-
-    public Integer getSelectedDataSetId()
-    {
-        return selectedDataSetId;
-    }
-
-    private Integer selectedPeriodIndex;
-
-    public void setSelectedPeriodIndex( Integer selectedPeriodIndex )
-    {
-        this.selectedPeriodIndex = selectedPeriodIndex;
-    }
-
-    public Integer getSelectedPeriodIndex()
-    {
-        return selectedPeriodIndex;
+    private Integer dataSetId;
+
+    public void setDataSetId( Integer dataSetId )
+    {
+        this.dataSetId = dataSetId;
+    }
+
+    private String periodId;
+
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
+    
+    private boolean defaultForm;
+
+    public void setDefaultForm( boolean defaultForm )
+    {
+        this.defaultForm = defaultForm;
     }
 
     private Map<Integer, Map<Integer, Collection<DataElementCategoryOption>>> orderedOptionsMap = new HashMap<Integer, Map<Integer, Collection<DataElementCategoryOption>>>();
@@ -326,13 +308,6 @@
         return greyedFields;
     }
 
-    private Integer defaultOptionComboId;
-
-    public Integer getDefaultOptionComboId()
-    {
-        return defaultOptionComboId;
-    }
-
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -340,47 +315,25 @@
     public String execute()
         throws Exception
     {
-        organisationUnit = selectedStateManager.getSelectedOrganisationUnit();
-
-        DataSet selectedDataSet = selectedStateManager.getSelectedDataSet();
-
-        // ---------------------------------------------------------------------
-        // Validate selected period
-        // ---------------------------------------------------------------------
-
-        if ( selectedPeriodIndex == null )
-        {
-            selectedPeriodIndex = selectedStateManager.getSelectedPeriodIndex();
-        }
-
-        if ( selectedPeriodIndex != null && selectedPeriodIndex >= 0 )
-        {
-            selectedStateManager.setSelectedPeriodIndex( selectedPeriodIndex );
-
-            period = selectedStateManager.getSelectedPeriod();
-        }
-        else
-        {
-            selectedStateManager.clearSelectedPeriod();
-
-            return INPUT;
-        }
+        organisationUnit = selectionManager.getSelectedOrganisationUnit();
+
+        DataSet dataSet = dataSetService.getDataSet( dataSetId );
+
+        Period period = PeriodType.createPeriodExternalId( periodId );
 
         // ---------------------------------------------------------------------
         // Get data locking info
         // ---------------------------------------------------------------------
 
-        if ( selectedDataSet != null )
+        if ( dataSet != null && period != null )
         {
-            period = selectedStateManager.getSelectedPeriod();
-
-            DataSetLock dataSetLock = dataSetLockService.getDataSetLockByDataSetAndPeriod( selectedDataSet, period );
+            DataSetLock dataSetLock = dataSetLockService.getDataSetLockByDataSetAndPeriod( dataSet, period );
 
             if ( dataSetLock != null && dataSetLock.getSources().contains( organisationUnit ) )
             {
                 locked = true;
 
-                log.info( "Dataset '" + selectedDataSet.getName() + "' is locked " );
+                log.info( "Dataset '" + dataSet.getName() + "' is locked " );
             }
         }
 
@@ -388,9 +341,9 @@
         // Get data set completeness info
         // ---------------------------------------------------------------------
 
-        if ( selectedDataSet != null && period != null && organisationUnit != null )
+        if ( dataSet != null && period != null && organisationUnit != null )
         {
-            registration = registrationService.getCompleteDataSetRegistration( selectedDataSet, period,
+            registration = registrationService.getCompleteDataSetRegistration( dataSet, period,
                 organisationUnit );
 
             registrationDate = registration != null ? registration.getDate() : new Date();
@@ -400,23 +353,9 @@
         // Get display mode
         // ---------------------------------------------------------------------
 
-        if ( !selectedStateManager.displayModeIsValid( displayMode ) )
-        {
-            displayMode = selectedStateManager.getSelectedDisplayMode();
-        }
-
-        if ( !selectedStateManager.displayModeIsValid( displayMode ) )
-        {
-            displayMode = selectedStateManager.getDisplayMode();
-        }
-
-        selectedStateManager.setSelectedDisplayMode( displayMode );
-
-        // ---------------------------------------------------------------------
-        // Get entry form
-        // ---------------------------------------------------------------------
-
-        List<DataElement> dataElements = new ArrayList<DataElement>( selectedDataSet.getDataElements() );
+        String displayMode = defaultForm ? DataSet.TYPE_DEFAULT : dataSet.getDataSetType();
+        
+        List<DataElement> dataElements = new ArrayList<DataElement>( dataSet.getDataElements() );
 
         if ( dataElements.isEmpty() )
         {
@@ -425,10 +364,6 @@
         
         Collections.sort( dataElements, dataElementComparator );
 
-        // ---------------------------------------------------------------------
-        // Get the min/max values
-        // ---------------------------------------------------------------------
-
         orderedDataElements = dataElementService.getGroupedDataElementsByCategoryCombo( dataElements );
 
         orderedCategoryCombos = dataElementService.getDataElementCategoryCombos( dataElements );
@@ -499,13 +434,13 @@
         // Get data entry form
         // ---------------------------------------------------------------------
 
-        if ( displayMode.equals( SECTION_FORM ) )
+        if ( displayMode.equals( DataSet.TYPE_SECTION ) )
         {
-            getSectionForm( dataElements, selectedDataSet );
+            getSectionForm( dataElements, dataSet );
         }
         else
         {
-            getOtherDataEntryForm( dataElements, selectedDataSet );
+            getOtherDataEntryForm( dataElements, dataSet, locked );
         }
 
         return displayMode;
@@ -517,18 +452,10 @@
 
     private void getSectionForm( Collection<DataElement> dataElements, DataSet dataSet )
     {
-        // ---------------------------------------------------------------------
-        // Order the Sections
-        // ---------------------------------------------------------------------
-
         sections = new ArrayList<Section>( dataSet.getSections() );
 
         Collections.sort( sections, new SectionOrderComparator() );
 
-        // ---------------------------------------------------------------------
-        // Get the category combos for the sections
-        // ---------------------------------------------------------------------
-
         for ( Section section : sections )
         {
             DataElementCategoryCombo sectionCategoryCombo = section.getCategoryCombo();
@@ -551,20 +478,11 @@
                     true );
             }
         }
-
-        defaultOptionComboId = categoryService.getDefaultDataElementCategoryOptionCombo().getId();
-
     }
 
-    private void getOtherDataEntryForm( List<DataElement> dataElements, DataSet dataSet )
+    private void getOtherDataEntryForm( List<DataElement> dataElements, DataSet dataSet, boolean locked )
     {
-        DataSetLock dataSetLock = dataSetLockService.getDataSetLockByDataSetAndPeriod( dataSet, period );
-
-        String disabled = dataSetLock != null && dataSetLock.getSources().contains( organisationUnit ) ? "disabled" : "";
-
-        // ---------------------------------------------------------------------
-        // Get the custom data entry form (if any)
-        // ---------------------------------------------------------------------
+        String disabled = locked ? "disabled" : "";
 
         DataEntryForm dataEntryForm = dataSet.getDataEntryForm();
 
@@ -574,10 +492,6 @@
                 dataEntryForm.getHtmlCode(), disabled, i18n, dataSet );
         }
 
-        // ---------------------------------------------------------------------
-        // Working on the display of data elements
-        // ---------------------------------------------------------------------
-
         List<DataElement> des = new ArrayList<DataElement>();
 
         for ( DataElementCategoryCombo categoryCombo : orderedCategoryCombos )

=== removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadNextPreviousPeriodsAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadNextPreviousPeriodsAction.java	2011-05-20 13:28:27 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadNextPreviousPeriodsAction.java	1970-01-01 00:00:00 +0000
@@ -1,117 +0,0 @@
-package org.hisp.dhis.de.action;
-
-/*
- * Copyright (c) 2004-2010, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- *   be used to endorse or promote products derived from this software without
- *   specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.hisp.dhis.de.state.SelectedStateManager;
-import org.hisp.dhis.i18n.I18nFormat;
-import org.hisp.dhis.period.Period;
-
-import com.opensymphony.xwork2.Action;
-
-/**
- * @author Lars Helge Overland
- */
-public class LoadNextPreviousPeriodsAction
-    implements Action
-{
-    // -------------------------------------------------------------------------
-    // Dependencies
-    // -------------------------------------------------------------------------
-
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
-
-    private I18nFormat format;
-
-    public void setFormat( I18nFormat format )
-    {
-        this.format = format;
-    }
-
-    // -------------------------------------------------------------------------
-    // Input
-    // -------------------------------------------------------------------------
-
-    private boolean next;
-
-    public void setNext( boolean next )
-    {
-        this.next = next;
-    }
-
-    private boolean previous;
-
-    public void setPrevious( boolean previous )
-    {
-        this.previous = previous;
-    }
-    
-    // -------------------------------------------------------------------------
-    // Output
-    // -------------------------------------------------------------------------
-
-    private List<Period> periods = new ArrayList<Period>();
-
-    public Collection<Period> getPeriods()
-    {
-        return periods;
-    }
-
-    // -------------------------------------------------------------------------
-    // Action implementation
-    // -------------------------------------------------------------------------
-
-    public String execute()
-    {
-        if ( next )
-        {
-            selectedStateManager.nextPeriodSpan();
-        }
-        else if ( previous )
-        {
-            selectedStateManager.previousPeriodSpan();
-        }
-
-        periods = selectedStateManager.getPeriodList();
-        
-        for ( Period period : periods )
-        {
-            period.setName( format.formatPeriod( period ) );
-        }
-        
-        return SUCCESS;
-    }
-}

=== removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadPeriodsAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadPeriodsAction.java	2011-07-14 10:34:09 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadPeriodsAction.java	1970-01-01 00:00:00 +0000
@@ -1,149 +0,0 @@
-package org.hisp.dhis.de.action;
-
-/*
- * Copyright (c) 2004-2010, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- *   be used to endorse or promote products derived from this software without
- *   specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.hisp.dhis.dataset.DataSet;
-import org.hisp.dhis.dataset.DataSetService;
-import org.hisp.dhis.de.state.SelectedStateManager;
-import org.hisp.dhis.i18n.I18nFormat;
-import org.hisp.dhis.period.Period;
-
-import com.opensymphony.xwork2.Action;
-
-/**
- * @author Lars Helge Overland
- */
-public class LoadPeriodsAction
-    implements Action
-{
-    // -------------------------------------------------------------------------
-    // Dependencies
-    // -------------------------------------------------------------------------
-
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
-
-    private DataSetService dataSetService;
-
-    public void setDataSetService( DataSetService dataSetService )
-    {
-        this.dataSetService = dataSetService;
-    }
-    
-    private I18nFormat format;
-
-    public void setFormat( I18nFormat format )
-    {
-        this.format = format;
-    }
-    
-    // -------------------------------------------------------------------------
-    // Input
-    // -------------------------------------------------------------------------
-
-    private Integer dataSetId;
-
-    public void setDataSetId( Integer dataSetId )
-    {
-        this.dataSetId = dataSetId;
-    }
-    
-    // -------------------------------------------------------------------------
-    // Output
-    // -------------------------------------------------------------------------
-
-    private List<Period> periods = new ArrayList<Period>();
-
-    public Collection<Period> getPeriods()
-    {
-        return periods;
-    }
-
-    private boolean periodValid;
-
-    public boolean isPeriodValid()
-    {
-        return periodValid;
-    }
-    
-    // -------------------------------------------------------------------------
-    // Action implementation
-    // -------------------------------------------------------------------------
-
-    public String execute()
-    {
-        DataSet selectedDataSet = dataSetService.getDataSet( dataSetId );
-        
-        if ( selectedDataSet != null )
-        {
-            // -----------------------------------------------------------------
-            // Check if previous data set has same period type as selected
-            // -----------------------------------------------------------------
-
-            DataSet previousDataSet = selectedStateManager.getSelectedDataSet();
-            
-            if ( previousDataSet != null && previousDataSet.getPeriodType().equals( selectedDataSet.getPeriodType() ) )
-            {
-                periodValid = true;
-            }
-            else
-            {
-                selectedStateManager.clearSelectedPeriod();
-            }
-
-            // -----------------------------------------------------------------
-            // Load periods for period type of selected data set
-            // -----------------------------------------------------------------
-
-            selectedStateManager.setSelectedDataSet( selectedDataSet );
-            
-            periods = selectedStateManager.getPeriodList();
-            
-            for ( Period period : periods )
-            {
-                period.setName( format.formatPeriod( period ) );
-            }
-            
-            // -----------------------------------------------------------------
-            // Clear display mode when loading new data set
-            // -----------------------------------------------------------------
-
-            selectedStateManager.clearSelectedDisplayMode();
-        }
-
-        return SUCCESS;
-    }
-}

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/PageInitAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/PageInitAction.java	2011-07-14 10:31:16 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/PageInitAction.java	2011-07-19 21:49:16 +0000
@@ -31,7 +31,8 @@
 
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementService;
-import org.hisp.dhis.de.state.SelectedStateManager;
+import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.expression.ExpressionService;
 import org.hisp.dhis.indicator.Indicator;
 import org.hisp.dhis.indicator.IndicatorService;
@@ -47,13 +48,6 @@
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
-
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
     
     private DataElementService dataElementService;
 
@@ -75,6 +69,13 @@
     {
         this.expressionService = expressionService;
     }
+    
+    private DataSetService dataSetService;
+
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
 
     // -------------------------------------------------------------------------
     // Output
@@ -93,21 +94,26 @@
     {
         return indicators;
     }
+    
+    private Collection<DataSet> dataSets;
+
+    public Collection<DataSet> getDataSets()
+    {
+        return dataSets;
+    }
 
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
 
     public String execute()
-    {        
-        selectedStateManager.clearSelectedOrganisationUnits();
-        selectedStateManager.clearSelectedDataSet();
-        selectedStateManager.clearSelectedPeriod();
-
+    {
         significantZeros = dataElementService.getDataElementsByZeroIsSignificant( true );
         
         indicators = indicatorService.getIndicatorsWithDataSets();
         
+        dataSets = dataSetService.getAllDataSets();
+        
         for ( Indicator indicator : indicators )
         {
             indicator.setExplodedNumerator( expressionService.explodeExpression( indicator.getNumerator() ) );

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/RegisterCompleteDataSetAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/RegisterCompleteDataSetAction.java	2011-01-25 16:02:32 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/RegisterCompleteDataSetAction.java	2011-07-20 19:58:06 +0000
@@ -33,7 +33,9 @@
 import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.dataset.CompleteDataSetRegistration;
 import org.hisp.dhis.dataset.CompleteDataSetRegistrationService;
-import org.hisp.dhis.de.state.SelectedStateManager;
+import org.hisp.dhis.dataset.DataSetService;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
+import org.hisp.dhis.period.PeriodType;
 
 import com.opensymphony.xwork2.Action;
 
@@ -57,11 +59,36 @@
         this.registrationService = registrationService;
     }
 
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
+    private OrganisationUnitSelectionManager selectionManager;
+
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
+    {
+        this.selectionManager = selectionManager;
+    }
+    
+    private DataSetService dataSetService;
+
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private String periodId;
+
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
+
+    private Integer dataSetId;
+
+    public void setDataSetId( Integer dataSetId )
+    {
+        this.dataSetId = dataSetId;
     }
 
     // -------------------------------------------------------------------------
@@ -72,9 +99,9 @@
     {
         CompleteDataSetRegistration registration = new CompleteDataSetRegistration();
 
-        registration.setDataSet( selectedStateManager.getSelectedDataSet() );
-        registration.setPeriod( selectedStateManager.getSelectedPeriod() );
-        registration.setSource( selectedStateManager.getSelectedOrganisationUnit() );
+        registration.setDataSet( dataSetService.getDataSet( dataSetId ) );
+        registration.setPeriod( PeriodType.createPeriodExternalId( periodId ) );
+        registration.setSource( selectionManager.getSelectedOrganisationUnit() );
         registration.setDate( new Date() );
 
         registrationService.saveCompleteDataSetRegistration( registration );

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveCommentAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveCommentAction.java	2011-01-25 16:14:19 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveCommentAction.java	2011-07-20 21:38:30 +0000
@@ -37,10 +37,10 @@
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.datavalue.DataValue;
 import org.hisp.dhis.datavalue.DataValueService;
-import org.hisp.dhis.de.state.SelectedStateManager;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodType;
 import org.hisp.dhis.user.CurrentUserService;
 
 import com.opensymphony.xwork2.Action;
@@ -79,13 +79,6 @@
         this.dataValueService = dataValueService;
     }
 
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
-
     private DataElementCategoryService categoryService;
 
     public void setCategoryService( DataElementCategoryService categoryService )
@@ -104,6 +97,13 @@
     // Input/output
     // -------------------------------------------------------------------------
 
+    private String periodId;
+    
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
+
     private String comment;
 
     public void setComment( String comment )
@@ -152,7 +152,7 @@
     {
         OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( organisationUnitId );
 
-        Period period = selectedStateManager.getSelectedPeriod();
+        Period period = PeriodType.createPeriodExternalId( periodId );
 
         DataElement dataElement = dataElementService.getDataElement( dataElementId );
 

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java	2011-07-18 10:22:08 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java	2011-07-19 21:49:16 +0000
@@ -35,10 +35,10 @@
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.datavalue.DataValue;
 import org.hisp.dhis.datavalue.DataValueService;
-import org.hisp.dhis.de.state.SelectedStateManager;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodType;
 import org.hisp.dhis.user.CurrentUserService;
 
 import com.opensymphony.xwork2.Action;
@@ -74,13 +74,6 @@
         this.dataValueService = dataValueService;
     }
 
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
-
     private DataElementCategoryService categoryService;
 
     public void setCategoryService( DataElementCategoryService categoryService )
@@ -126,6 +119,13 @@
     {
         this.optionComboId = optionComboId;
     }
+    
+    private String periodId;
+
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
 
     // -------------------------------------------------------------------------
     // Output
@@ -146,7 +146,7 @@
     {
         OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( organisationUnitId );
 
-        Period period = selectedStateManager.getSelectedPeriod();
+        Period period = PeriodType.createPeriodExternalId( periodId );
 
         DataElement dataElement = dataElementService.getDataElement( dataElementId );
 

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/UndoCompleteDataSetAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/UndoCompleteDataSetAction.java	2011-05-20 13:28:27 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/UndoCompleteDataSetAction.java	2011-07-20 19:58:06 +0000
@@ -32,9 +32,11 @@
 import org.hisp.dhis.dataset.CompleteDataSetRegistration;
 import org.hisp.dhis.dataset.CompleteDataSetRegistrationService;
 import org.hisp.dhis.dataset.DataSet;
-import org.hisp.dhis.de.state.SelectedStateManager;
+import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodType;
 
 import com.opensymphony.xwork2.Action;
 
@@ -56,23 +58,48 @@
     {
         this.registrationService = registrationService;
     }
-    
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
-    
+
+    private OrganisationUnitSelectionManager selectionManager;
+
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
+    {
+        this.selectionManager = selectionManager;
+    }
+    
+    private DataSetService dataSetService;
+
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private String periodId;
+
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
+
+    private Integer dataSetId;
+
+    public void setDataSetId( Integer dataSetId )
+    {
+        this.dataSetId = dataSetId;
+    }
+
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
 
     public String execute()
     {        
-        DataSet dataSet = selectedStateManager.getSelectedDataSet();
-        Period period = selectedStateManager.getSelectedPeriod();
-        OrganisationUnit unit = selectedStateManager.getSelectedOrganisationUnit();
+        DataSet dataSet = dataSetService.getDataSet( dataSetId );
+        Period period = PeriodType.createPeriodExternalId( periodId );
+        OrganisationUnit unit = selectionManager.getSelectedOrganisationUnit();
         
         CompleteDataSetRegistration registration = registrationService.getCompleteDataSetRegistration( dataSet, period, unit );
         

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java	2011-06-12 08:23:05 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java	2011-07-20 19:58:06 +0000
@@ -39,16 +39,18 @@
 import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.dataanalysis.DataAnalysisService;
 import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.datavalue.DeflatedDataValue;
-import org.hisp.dhis.de.state.SelectedStateManager;
 import org.hisp.dhis.expression.ExpressionService;
 import org.hisp.dhis.minmax.MinMaxDataElement;
 import org.hisp.dhis.minmax.MinMaxDataElementService;
 import org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService;
 import org.hisp.dhis.options.SystemSettingManager;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
+import org.hisp.dhis.period.PeriodType;
 import org.hisp.dhis.system.util.ListUtils;
 import org.hisp.dhis.validation.ValidationResult;
 import org.hisp.dhis.validation.ValidationRule;
@@ -78,13 +80,6 @@
         this.validationRuleService = validationRuleService;
     }
 
-    private SelectedStateManager selectedStateManager;
-
-    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
-    {
-        this.selectedStateManager = selectedStateManager;
-    }
-
     private ExpressionService expressionService;
 
     public void setExpressionService( ExpressionService expressionService )
@@ -134,6 +129,38 @@
         this.minMaxDataElementService = minMaxDataElementService;
     }
 
+    private OrganisationUnitSelectionManager selectionManager;
+
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
+    {
+        this.selectionManager = selectionManager;
+    }
+    
+    private DataSetService dataSetService;
+
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private String periodId;
+
+    public void setPeriodId( String periodId )
+    {
+        this.periodId = periodId;
+    }
+
+    private Integer dataSetId;
+
+    public void setDataSetId( Integer dataSetId )
+    {
+        this.dataSetId = dataSetId;
+    }
+
     // -------------------------------------------------------------------------
     // Output
     // -------------------------------------------------------------------------
@@ -174,16 +201,16 @@
     public String execute()
         throws Exception
     {
-        OrganisationUnit orgUnit = selectedStateManager.getSelectedOrganisationUnit();
+        OrganisationUnit orgUnit = selectionManager.getSelectedOrganisationUnit();
 
-        Period selectedPeriod = selectedStateManager.getSelectedPeriod();
+        Period selectedPeriod = PeriodType.createPeriodExternalId( periodId );
 
         if ( orgUnit != null && selectedPeriod != null )
         {
             Period period = periodService.getPeriod( selectedPeriod.getStartDate(), selectedPeriod.getEndDate(),
                 selectedPeriod.getPeriodType() );
     
-            DataSet dataSet = selectedStateManager.getSelectedDataSet();
+            DataSet dataSet = dataSetService.getDataSet( dataSetId );
     
             // ---------------------------------------------------------------------
             // Min-max and outlier analysis

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/history/DefaultHistoryRetriever.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/history/DefaultHistoryRetriever.java	2010-04-12 21:23:33 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/history/DefaultHistoryRetriever.java	2011-07-20 21:38:30 +0000
@@ -81,13 +81,7 @@
     {
         if ( !dataElement.getType().equals( DataElement.VALUE_TYPE_INT ) )
         {
-            return null;
-
-            /*
-             * throw new HistoryRetrieverException(
-             * "DataElement is not of type " + DataElement.TYPE_INT + ": " +
-             * dataElement.getShortName() ) ;
-             */
+            return null; // TODO
         }
 
         // ---------------------------------------------------------------------
@@ -143,10 +137,8 @@
 
         history.setMaxHistoryValue( max );
 
-        // get the maxValue
         double maxValue = getMaxValue( history );
 
-        // if there was any entred values, set minValue and maxValue
         if ( maxValue != Double.NEGATIVE_INFINITY )
         {
             history.setMaxValue( maxValue );

=== removed directory 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state'
=== removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/DefaultSelectedStateManager.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/DefaultSelectedStateManager.java	2011-07-14 11:21:28 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/DefaultSelectedStateManager.java	1970-01-01 00:00:00 +0000
@@ -1,354 +0,0 @@
-package org.hisp.dhis.de.state;
-
-/*
- * Copyright (c) 2004-2010, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- *   be used to endorse or promote products derived from this software without
- *   specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hisp.dhis.dataset.DataSet;
-import org.hisp.dhis.dataset.DataSetService;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
-import org.hisp.dhis.period.CalendarPeriodType;
-import org.hisp.dhis.period.Period;
-import org.hisp.dhis.period.PeriodService;
-import org.hisp.dhis.period.PeriodType;
-import org.hisp.dhis.user.CurrentUserService;
-import org.hisp.dhis.user.User;
-
-import com.opensymphony.xwork2.ActionContext;
-
-/**
- * @author Torgeir Lorange Ostby
- * @version $Id: DefaultSelectedStateManager.java 5282 2008-05-28 10:41:06Z
- *          larshelg $
- */
-public class DefaultSelectedStateManager
-    implements SelectedStateManager
-{
-    public static final String SESSION_KEY_SELECTED_DATASET_ID = "data_entry_selected_dataset_id";
-    public static final String SESSION_KEY_SELECTED_PERIOD_INDEX = "data_entry_selected_period_index";
-    public static final String SESSION_KEY_BASE_PERIOD = "data_entry_base_period";    
-    public static final String SESSION_KEY_SELECTED_DISPLAY_MODE = "data_entry_selected_display_mode";
-
-    // -------------------------------------------------------------------------
-    // Dependencies
-    // -------------------------------------------------------------------------
-    
-    private DataSetService dataSetService;
-
-    public void setDataSetService( DataSetService dataSetService )
-    {
-        this.dataSetService = dataSetService;
-    }
-
-    private OrganisationUnitSelectionManager selectionManager;
-
-    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
-    {
-        this.selectionManager = selectionManager;
-    }
-
-    private CurrentUserService currentUserService;
-
-    public void setCurrentUserService( CurrentUserService currentUserService )
-    {
-        this.currentUserService = currentUserService;
-    }
-
-    public PeriodService periodService;
-
-    public void setPeriodService( PeriodService periodService )
-    {
-        this.periodService = periodService;
-    }
-    
-    // -------------------------------------------------------------------------
-    // SelectedStateManager implementation
-    // -------------------------------------------------------------------------
-
-    // -------------------------------------------------------------------------
-    // OrganisationUnit
-    // -------------------------------------------------------------------------
-    
-    public OrganisationUnit getSelectedOrganisationUnit()
-    {
-        return selectionManager.getSelectedOrganisationUnit();
-    }
-    
-    public void clearSelectedOrganisationUnits()
-    {
-        selectionManager.clearSelectedOrganisationUnits();
-    }
-    
-    // -------------------------------------------------------------------------
-    // DataSet
-    // -------------------------------------------------------------------------
-    
-    public void setSelectedDataSet( DataSet dataSet )
-    {
-        getSession().put( SESSION_KEY_SELECTED_DATASET_ID, dataSet.getId() );
-    }
-
-    public DataSet getSelectedDataSet()
-    {
-        Integer id = (Integer) getSession().get( SESSION_KEY_SELECTED_DATASET_ID );
-
-        return id != null ? dataSetService.getDataSet( id ) : null;
-    }
-
-    public void clearSelectedDataSet()
-    {
-        getSession().remove( SESSION_KEY_SELECTED_DATASET_ID );
-    }
-
-    public List<DataSet> loadDataSetsForSelectedOrgUnit()
-    {
-        List<DataSet> dataSets = new ArrayList<DataSet>( getSelectedOrganisationUnit().getDataSets() );
-
-        // ---------------------------------------------------------------------
-        // Retain only DataSets from current user's authority groups
-        // ---------------------------------------------------------------------
-
-        User currentUser = currentUserService.getCurrentUser();
-        
-        if ( currentUser != null && !currentUserService.currentUserIsSuper() )
-        {
-            dataSets.retainAll( currentUser.getUserCredentials().getAllDataSets() );
-        }
-
-        // ---------------------------------------------------------------------
-        // Remove DataSets which don't have a CalendarPeriodType
-        // ---------------------------------------------------------------------
-
-        Iterator<DataSet> iterator = dataSets.iterator();
-
-        while ( iterator.hasNext() )
-        {
-            DataSet dataSet = iterator.next();
-
-            if ( !( dataSet.getPeriodType() instanceof CalendarPeriodType) )
-            {
-                iterator.remove();
-            }
-        }
-
-        return dataSets;
-    }
-    
-    // -------------------------------------------------------------------------
-    // Period
-    // -------------------------------------------------------------------------
-    
-    public void setSelectedPeriodIndex( Integer index )
-    {
-        getSession().put( SESSION_KEY_SELECTED_PERIOD_INDEX, index );
-    }
-
-    public Integer getSelectedPeriodIndex()
-    {
-        return (Integer) getSession().get( SESSION_KEY_SELECTED_PERIOD_INDEX );
-    }
-
-    public Period getSelectedPeriod()
-    {
-        Integer index = getSelectedPeriodIndex();
-
-        if ( index == null )
-        {
-            return null;
-        }
-
-        List<Period> periods = getPeriodList();
-
-        if ( index >= 0 && index < periods.size() )
-        {
-            return periods.get( index );
-        }
-
-        return null;
-    }
-
-    public void clearSelectedPeriod()
-    {
-        getSession().remove( SESSION_KEY_SELECTED_PERIOD_INDEX );
-    }
-
-    public List<Period> getPeriodList()
-    {
-        if ( getSelectedDataSet() == null )
-        {
-            return new ArrayList<Period>();
-        }
-        
-        Period basePeriod = getBasePeriod();
-        
-        CalendarPeriodType periodType = (CalendarPeriodType) getPeriodType();
-
-        List<Period> periods = periodType.generatePeriods( basePeriod );
-
-        Date now = new Date();
-
-        Iterator<Period> iterator = periods.iterator();
-        
-        while ( iterator.hasNext() )
-        {
-            if ( iterator.next().getStartDate().after( now ) )
-            {
-                iterator.remove();
-            }
-        }
-        
-        return periods;
-    }
-    
-    public void nextPeriodSpan()
-    {
-        if ( getSelectedDataSet() != null )
-        {
-            List<Period> periods = getPeriodList();
-            CalendarPeriodType periodType = (CalendarPeriodType) getPeriodType();
-    
-            Period basePeriod = periods.get( periods.size() - 1 );
-            Period newBasePeriod = periodType.getNextPeriod( basePeriod );
-    
-            if ( newBasePeriod.getStartDate().before( new Date() ) ) // Future periods not allowed
-            {
-                getSession().put( SESSION_KEY_BASE_PERIOD, newBasePeriod );
-            }
-        }
-    }
-
-    public void previousPeriodSpan()
-    {
-        if ( getSelectedDataSet() != null )
-        {
-            List<Period> periods = getPeriodList();
-            CalendarPeriodType periodType = (CalendarPeriodType) getPeriodType();
-    
-            Period basePeriod = periods.get( 0 );
-            Period newBasePeriod = periodType.getPreviousPeriod( basePeriod );
-    
-            getSession().put( SESSION_KEY_BASE_PERIOD, newBasePeriod );
-        }
-    }
-
-    public Period reloadPeriod()
-    {        
-        Period period = getSelectedPeriod();
-
-        return periodService.reloadPeriod( period );
-    }
-
-    // -------------------------------------------------------------------------
-    // DisplayMode
-    // -------------------------------------------------------------------------
-    
-    public void setSelectedDisplayMode( String displayMode )
-    {
-        getSession().put( SESSION_KEY_SELECTED_DISPLAY_MODE, displayMode );
-    }
-    
-    public String getSelectedDisplayMode()
-    {
-        return (String) getSession().get( SESSION_KEY_SELECTED_DISPLAY_MODE );
-    }
-    
-    public void clearSelectedDisplayMode()
-    {
-        getSession().remove( SESSION_KEY_SELECTED_DISPLAY_MODE );
-    }
-    
-    public boolean displayModeIsValid( String displayMode )
-    {
-        DataSet dataSet = getSelectedDataSet();
-        
-        final Map<String, Boolean> map = new HashMap<String, Boolean>();
-        map.put( CUSTOM_FORM, dataSet.hasDataEntryForm() );
-        map.put( SECTION_FORM, dataSet.hasSections() );
-        map.put( DEFAULT_FORM, true );
-        
-        return displayMode != null && map.containsKey( displayMode ) ? map.get( displayMode ) : false;
-    }
-    
-    public String getDisplayMode()
-    {
-        DataSet dataSet = getSelectedDataSet();
-        
-        if ( dataSet.hasDataEntryForm() )
-        {
-            return CUSTOM_FORM;
-        }
-        else if ( dataSet.hasSections() )
-        {
-            return SECTION_FORM;
-        }
-        
-        return DEFAULT_FORM;
-    }
-    
-    // -------------------------------------------------------------------------
-    // Support methods
-    // -------------------------------------------------------------------------
-
-    private PeriodType getPeriodType()
-    {
-        DataSet dataSet = getSelectedDataSet();
-
-        return dataSet != null ? dataSet.getPeriodType() : null;
-    }
-
-    private Period getBasePeriod()
-    {
-        Period basePeriod = (Period) getSession().get( SESSION_KEY_BASE_PERIOD );
-        
-        PeriodType periodType = getPeriodType();
-
-        if ( basePeriod == null )
-        {
-            basePeriod = periodType.createPeriod();
-            getSession().put( SESSION_KEY_BASE_PERIOD, basePeriod );
-        }
-        else if ( !basePeriod.getPeriodType().equals( periodType ) )
-        {
-            basePeriod = periodType.createPeriod( basePeriod.getStartDate() );
-            getSession().put( SESSION_KEY_BASE_PERIOD, basePeriod );
-        }
-
-        return basePeriod;
-    }
-
-    private static final Map<String, Object> getSession()
-    {
-        return ActionContext.getContext().getSession();
-    }
-}

=== removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/SelectedStateManager.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/SelectedStateManager.java	2011-01-24 19:40:35 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/SelectedStateManager.java	1970-01-01 00:00:00 +0000
@@ -1,102 +0,0 @@
-package org.hisp.dhis.de.state;
-
-/*
- * Copyright (c) 2004-2010, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- *   be used to endorse or promote products derived from this software without
- *   specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.hisp.dhis.dataset.DataSet;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.period.Period;
-
-/**
- * @author Torgeir Lorange Ostby
- * @version $Id: SelectedStateManager.java 3311 2007-05-18 14:08:01Z torgeilo $
- */
-public interface SelectedStateManager
-{
-    final String CUSTOM_FORM = "customform";
-    final String SECTION_FORM = "sectionform";
-    final String DEFAULT_FORM = "defaultform";
-    
-    final List<String> ALLOWED_FORM_TYPES = Arrays.asList( CUSTOM_FORM, SECTION_FORM, DEFAULT_FORM );
-
-    // -------------------------------------------------------------------------
-    // OrganisationUnit
-    // -------------------------------------------------------------------------
-    
-    OrganisationUnit getSelectedOrganisationUnit();  
-
-    void clearSelectedOrganisationUnits();
-    
-    // -------------------------------------------------------------------------
-    // DataSet
-    // -------------------------------------------------------------------------
-    
-    void setSelectedDataSet( DataSet dataSet );
-
-    DataSet getSelectedDataSet();
-
-    void clearSelectedDataSet();
-    
-    List<DataSet> loadDataSetsForSelectedOrgUnit();    
-
-    // -------------------------------------------------------------------------
-    // Period
-    // -------------------------------------------------------------------------
-    
-    void setSelectedPeriodIndex( Integer index );
-
-    Integer getSelectedPeriodIndex();
-
-    Period getSelectedPeriod();
-
-    void clearSelectedPeriod();
-
-    List<Period> getPeriodList();
-
-    void nextPeriodSpan();
-
-    void previousPeriodSpan();
-    
-    Period reloadPeriod();
-
-    // -------------------------------------------------------------------------
-    // DisplayMode
-    // -------------------------------------------------------------------------
-    
-    void setSelectedDisplayMode( String displayMode );
-    
-    String getSelectedDisplayMode();
-    
-    void clearSelectedDisplayMode();
-    
-    boolean displayModeIsValid( String displayMode );
-    
-    String getDisplayMode();
-}

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml	2011-07-14 10:34:09 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml	2011-07-20 21:38:30 +0000
@@ -9,54 +9,36 @@
     <property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
   </bean>
 
-  <bean id="org.hisp.dhis.de.state.SelectedStateManager" class="org.hisp.dhis.de.state.DefaultSelectedStateManager">
-    <property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
-    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
-    <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
-    <property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
-  </bean>
-
   <!-- Actions -->
 
   <bean id="org.hisp.dhis.de.action.PageInitAction" class="org.hisp.dhis.de.action.PageInitAction"
     scope="prototype">
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
 	<property name="indicatorService" ref="org.hisp.dhis.indicator.IndicatorService" />
 	<property name="expressionService" ref="org.hisp.dhis.expression.ExpressionService" />
+	<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
   </bean>
 
   <bean id="org.hisp.dhis.de.action.GetDataValuesForDataSetAction" class="org.hisp.dhis.de.action.GetDataValuesForDataSetAction"
 	scope="prototype">
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
 	<property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
 	<property name="minMaxDataElementService" ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
+    <property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
+    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
   </bean>
 
   <bean id="org.hisp.dhis.de.action.LoadDataSetsAction" class="org.hisp.dhis.de.action.LoadDataSetsAction" scope="prototype">
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
-  </bean>
-
-  <bean id="org.hisp.dhis.de.action.LoadPeriodsAction" class="org.hisp.dhis.de.action.LoadPeriodsAction" scope="prototype">
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
-    <property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
-  </bean>
-
-  <bean id="org.hisp.dhis.de.action.LoadNextPreviousPeriodsAction" class="org.hisp.dhis.de.action.LoadNextPreviousPeriodsAction"
-    scope="prototype">
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
-  </bean>
-
-  <bean id="org.hisp.dhis.de.action.LoadDisplayModesAction" class="org.hisp.dhis.de.action.LoadDisplayModesAction"
-    scope="prototype">
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
+    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
+	<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
+	<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
   </bean>
 
   <bean id="org.hisp.dhis.de.action.LoadFormAction" class="org.hisp.dhis.de.action.LoadFormAction" scope="prototype">
     <property name="dataEntryFormService" ref="org.hisp.dhis.dataentryform.DataEntryFormService" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
+	<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
     <property name="dataSetLockService" ref="org.hisp.dhis.datalock.DataSetLockService" />
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
+    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
     <property name="registrationService" ref="org.hisp.dhis.dataset.CompleteDataSetRegistrationService" />
     <property name="categoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
   </bean>
@@ -65,7 +47,6 @@
     <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
     <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
     <property name="categoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
     <property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
   </bean>
@@ -74,7 +55,6 @@
     <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
     <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
     <property name="categoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
     <property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
   </bean>
@@ -98,7 +78,7 @@
   <bean id="org.hisp.dhis.de.action.HistoryAction" class="org.hisp.dhis.de.action.HistoryAction" scope="prototype">
     <property name="historyRetriever" ref="org.hisp.dhis.de.history.HistoryRetriever" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
+    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
     <property name="categoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
     <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
     <property name="dataValueAuditService" ref="org.hisp.dhis.datavalue.DataValueAuditService" />
@@ -107,25 +87,28 @@
   <bean id="org.hisp.dhis.de.action.RegisterCompleteDataSetAction" class="org.hisp.dhis.de.action.RegisterCompleteDataSetAction"
     scope="prototype">
     <property name="registrationService" ref="org.hisp.dhis.dataset.CompleteDataSetRegistrationService" />
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
+    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
+	<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
   </bean>
 
   <bean id="org.hisp.dhis.de.action.UndoCompleteDataSetAction" class="org.hisp.dhis.de.action.UndoCompleteDataSetAction"
     scope="prototype">
     <property name="registrationService" ref="org.hisp.dhis.dataset.CompleteDataSetRegistrationService" />
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
+    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
+	<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
   </bean>
 
   <bean id="org.hisp.dhis.de.action.ValidationAction" class="org.hisp.dhis.de.action.ValidationAction" scope="prototype">
     <property name="validationRuleService" ref="org.hisp.dhis.validation.ValidationRuleService" />
     <property name="expressionService" ref="org.hisp.dhis.expression.ExpressionService" />
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
     <property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
     <property name="stdDevOutlierAnalysisService" ref="org.hisp.dhis.dataanalysis.StdDevOutlierAnalysisService" />
     <property name="minMaxOutlierAnalysisService" ref="org.hisp.dhis.dataanalysis.MinMaxOutlierAnalysisService" />
     <property name="minMaxValuesGenerationService" ref="org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService" />
     <property name="minMaxDataElementService" ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
     <property name="systemSettingManager" ref="org.hisp.dhis.options.SystemSettingManager" />
+    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
+	<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
   </bean>
 
   <bean id="org.hisp.dhis.de.action.MarkForFollowupAction" class="org.hisp.dhis.de.action.MarkForFollowupAction"
@@ -141,7 +124,7 @@
     scope="prototype">
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
     <property name="categoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
-    <property name="selectedStateManager" ref="org.hisp.dhis.de.state.SelectedStateManager" />
+    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
     <property name="chartService" ref="org.hisp.dhis.chart.ChartService" />
   </bean>
 

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml	2011-07-14 07:33:23 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml	2011-07-21 11:52:46 +0000
@@ -26,22 +26,10 @@
       <result name="success" type="velocity-json">/dhis-web-dataentry/responseDataSets.vm</result>
     </action>
 
-    <action name="loadPeriods" class="org.hisp.dhis.de.action.LoadPeriodsAction">
-      <result name="success" type="velocity-json">/dhis-web-dataentry/responsePeriods.vm</result>
-    </action>
-
-    <action name="loadNextPreviousPeriods" class="org.hisp.dhis.de.action.LoadNextPreviousPeriodsAction">
-      <result name="success" type="velocity-json">../dhis-web-commons/ajax/jsonPeriods.vm</result>
-    </action>
-
-    <action name="loadDisplayModes" class="org.hisp.dhis.de.action.LoadDisplayModesAction">
-      <result name="success" type="velocity-json">/dhis-web-dataentry/responseDisplayModes.vm</result>
-    </action>
-
     <action name="loadForm" class="org.hisp.dhis.de.action.LoadFormAction">
-      <result name="customform" type="velocity">/dhis-web-dataentry/customForm.vm</result>
-      <result name="sectionform" type="velocity">/dhis-web-dataentry/sectionForm.vm</result>
-      <result name="defaultform" type="velocity">/dhis-web-dataentry/defaultForm.vm</result>
+      <result name="custom" type="velocity">/dhis-web-dataentry/customForm.vm</result>
+      <result name="section" type="velocity">/dhis-web-dataentry/sectionForm.vm</result>
+      <result name="default" type="velocity">/dhis-web-dataentry/defaultForm.vm</result>
       <result name="input" type="velocity">/dhis-web-dataentry/responseVoid.vm</result>
     </action>
 

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/history.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/history.vm	2011-06-27 10:39:01 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/history.vm	2011-07-20 21:38:30 +0000
@@ -2,6 +2,7 @@
 	var currentOrganisationUnitId = $!{dataElementHistory.organisationUnit.id};
 	var currentDataElementId = $!{dataElementHistory.dataElement.id};
 	var currentOptionComboId = $!{dataElementHistory.optionCombo.id};
+	var currentPeriodId = '${periodId}';
 	
 	var i18n_enter_digits = '$encoder.jsEscape( $i18n.getString( "enter_digits" ) , "'")';
 	var i18n_max_must_be_greater_than_min = '$encoder.jsEscape( $i18n.getString( "max_must_be_greater_than_min" ) , "'")';
@@ -84,7 +85,7 @@
 			    <h4>$encoder.htmlEncode( $i18n.getString( "history_not_valid" ) )</h4>  
 			#end    
 			
-			<img id="historyChart" src="getHistoryChart.action?dataElementId=${dataElementHistory.dataElement.id}&categoryOptionComboId=${dataElementHistory.optionCombo.id}"/>			
+			<img id="historyChart" src="getHistoryChart.action?dataElementId=${dataElementHistory.dataElement.id}&categoryOptionComboId=${dataElementHistory.optionCombo.id}&periodId=${periodId}"/>			
         </td>
     </tr>
 	<tr>

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js	2011-07-14 10:31:16 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js	2011-07-19 21:49:16 +0000
@@ -99,6 +99,8 @@
 
     $( fieldId ).css( 'background-color', COLOR_YELLOW );
 
+	var periodId = $( '#selectedPeriodId' ).val();
+        
     if ( value )
     {
         if ( type == 'int' || type == 'number' || type == 'positiveNumber' || type == 'negativeNumber' )
@@ -144,7 +146,7 @@
 
                 if ( valueNo < min )
                 {
-                    var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, value, COLOR_ORANGE );
+                    var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, periodId, value, COLOR_ORANGE );
                     valueSaver.save();
 
                     window.alert( i18n_value_of_data_element_less + ': ' + min + '\n\n' + dataElementName );
@@ -153,7 +155,7 @@
 
                 if ( valueNo > max )
                 {
-                    var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, value, COLOR_ORANGE );
+                    var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, periodId, value, COLOR_ORANGE );
                     valueSaver.save();
 
                     window.alert( i18n_value_of_data_element_greater + ': ' + max + '\n\n' + dataElementName );
@@ -162,7 +164,7 @@
             }
         }
         
-	    var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, value, COLOR_GREEN );
+	    var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, periodId, value, COLOR_GREEN );
 	    valueSaver.save();
 	    
 	    updateIndicators(); // Update indicators in case of custom form
@@ -176,7 +178,9 @@
 
     $( fieldId ).css( 'background-color', COLOR_YELLOW );
 
-    var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, value, COLOR_GREEN );
+	var periodId = $( '#selectedPeriodId' ).val();
+        
+    var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, periodId, value, COLOR_GREEN );
     valueSaver.save();
 }
 
@@ -197,18 +201,19 @@
 // Saver objects
 // -----------------------------------------------------------------------------
 
-function ValueSaver( dataElementId_, optionComboId_, organisationUnitId_, value_, resultColor_ )
+function ValueSaver( dataElementId_, optionComboId_, organisationUnitId_, periodId_, value_, resultColor_ )
 {
     var dataElementId = dataElementId_;
     var optionComboId = optionComboId_;
     var value = value_;
     var resultColor = resultColor_;
     var organisationUnitId = organisationUnitId_;
+    var periodId = periodId_;
 
     this.save = function()
     {
         var url = 'saveValue.action?organisationUnitId=' + organisationUnitId + '&dataElementId=' + dataElementId
-                + '&optionComboId=' + optionComboId + '&value=' + value;
+                + '&optionComboId=' + optionComboId + '&periodId=' + periodId + '&value=' + value;
 
         $.ajax( {
             url : url,

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js	2011-07-14 10:31:16 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js	2011-07-21 11:52:46 +0000
@@ -1,15 +1,27 @@
 // Identifiers for which zero values are, insignificant, also used in entry.js, populated in select.vm
 var significantZeros = [];
 
-// Associative array with [indicator id, expression] for indicators in form, also used in entry.js
+// Associative array with [indicator id, expression] for indicators in form, also used in entry.js, populated in select.vm
 var indicatorFormulas = [];
 
+// Array with associative arrays for each data set, populated in select.vm
+var dataSets = [];
+
 // Indicates whether any data entry form has been loaded
 var dataEntryFormIsLoaded = false;
 
 // Currently selected organisation unit identifier
 var currentOrganisationUnitId = null;
 
+// Currently selected data set identifier
+var currentDataSetId = null;
+
+// Current offset, next or previous corresponding to increasing or decreasing value with one
+var currentPeriodOffset = 0;
+
+// Period type object
+var periodTypeFactory = new PeriodType();
+
 var COLOR_GREEN = '#b9ffb9';
 var COLOR_YELLOW = '#fffe8c';
 var COLOR_RED = '#ff8a8a';
@@ -24,7 +36,7 @@
 
 function clearPeriod()
 {
-    clearListById( 'selectedPeriodIndex' );
+    clearListById( 'selectedPeriodId' );
     clearEntryForm();
 }
 
@@ -32,9 +44,26 @@
 {
     $( '#contentDiv' ).html( '' );
     
+	currentPeriodOffset = 0;
+	
     dataEntryFormIsLoaded = false;
 }
 
+function loadForm( periodId, dataSetId )
+{
+	var defaultForm = $( '#defaultForm' ).is( ':checked' );
+	
+	$( '#contentDiv' ).load( 'loadForm.action', { periodId:periodId, dataSetId:dataSetId, defaultForm:defaultForm }, loadDataValues );
+}
+
+function loadDefaultForm()
+{
+    var dataSetId = $( '#selectedDataSetId' ).val();
+    var periodId = $( '#selectedPeriodId' ).val();
+
+	loadForm( periodId, dataSetId );
+}
+
 // -----------------------------------------------------------------------------
 // OrganisationUnit Selection
 // -----------------------------------------------------------------------------
@@ -46,12 +75,13 @@
     $( '#selectedDataSetId' ).removeAttr( 'disabled' );
 
     var dataSetId = $( '#selectedDataSetId' ).val();
+    var periodId = $( '#selectedPeriodId' ).val();
 
     var url = 'loadDataSets.action';
 
     clearListById( 'selectedDataSetId' );
 
-    $.getJSON( url, function( json )
+    $.getJSON( url, { dataSetId:dataSetId },  function( json )
     {
         $( '#selectedOrganisationUnit' ).val( json.organisationUnit.name );
         $( '#currentOrganisationUnit' ).html( json.organisationUnit.name );
@@ -67,7 +97,7 @@
         {
             $( '#selectedDataSetId' ).val( dataSetId );
 
-            if ( json.periodValid && dataEntryFormIsLoaded )
+            if ( periodId && periodId != -1 && dataEntryFormIsLoaded ) //TODO if period valid
             {
                 showLoader();
                 loadDataValues();
@@ -88,45 +118,34 @@
 
 function nextPeriodsSelected()
 {
-    displayPeriodsInternal( true, false );
+	if ( currentPeriodOffset < 0 ) // Cannot display future periods
+	{
+    	currentPeriodOffset++;
+    	displayPeriodsInternal();
+	}
 }
 
 function previousPeriodsSelected()
 {
-    displayPeriodsInternal( false, true );
+    currentPeriodOffset--;
+    displayPeriodsInternal();
 }
 
-function displayPeriodsInternal( next, previous )
+function displayPeriodsInternal()
 {
-    disableNextPrevButtons();
-
-    var url = 'loadNextPreviousPeriods.action?next=' + next + '&previous=' + previous;
-
-    clearListById( 'selectedPeriodIndex' );
-
-    $.getJSON( url, function( json )
+    var dataSetId = $( '#selectedDataSetId' ).val();    
+    var periodType = dataSets[dataSetId].periodType;
+    var periods = periodTypeFactory.get( periodType ).generatePeriods( currentPeriodOffset );
+    periods = periodTypeFactory.filterFuturePeriods( periods );
+
+	clearListById( 'selectedPeriodId' );
+
+	addOptionById( 'selectedPeriodId', '-1', '[ ' + i18n_select_period + ' ]' );
+
+    for ( i in periods )
     {
-        addOptionById( 'selectedPeriodIndex', '-1', '[ ' + i18n_select_period + ' ]' );
-
-        for ( i in json.periods )
-        {
-            addOptionById( 'selectedPeriodIndex', i, json.periods[i].name );
-        }
-
-        enableNextPrevButtons();
-    } );
-}
-
-function disableNextPrevButtons()
-{
-    $( '#nextButton' ).attr( 'disabled', 'disabled' );
-    $( '#prevButton' ).attr( 'disabled', 'disabled' );
-}
-
-function enableNextPrevButtons()
-{
-    $( '#nextButton' ).removeAttr( 'disabled' );
-    $( '#prevButton' ).removeAttr( 'disabled' );
+        addOptionById( 'selectedPeriodId', periods[i].id, periods[i].name );
+    }
 }
 
 // -----------------------------------------------------------------------------
@@ -135,80 +154,68 @@
 
 function dataSetSelected()
 {
-    $( '#selectedPeriodIndex' ).removeAttr( 'disabled' );
+    $( '#selectedPeriodId' ).removeAttr( 'disabled' );
     $( '#prevButton' ).removeAttr( 'disabled' );
     $( '#nextButton' ).removeAttr( 'disabled' );
 
     var dataSetId = $( '#selectedDataSetId' ).val();
-    var periodIndex = $( '#selectedPeriodIndex' ).val();
+    var periodId = $( '#selectedPeriodId' ).val();
+    var periodType = dataSets[dataSetId].periodType;
+	var periods = periodTypeFactory.get( periodType ).generatePeriods( currentPeriodOffset );
+    periods = periodTypeFactory.filterFuturePeriods( periods );
 
     if ( dataSetId && dataSetId != -1 )
     {
-        var url = 'loadPeriods.action?dataSetId=' + dataSetId;
-
-        clearListById( 'selectedPeriodIndex' );
-
-        $.getJSON( url, function( json )
-        {
-            addOptionById( 'selectedPeriodIndex', '-1', '[ ' + i18n_select_period + ' ]' );
-
-            for ( i in json.periods )
-            {
-                addOptionById( 'selectedPeriodIndex', i, json.periods[i].name );
-            }
-
-            if ( json.periodValid && periodIndex != null )
-            {
-                showLoader();
-                $( '#selectedPeriodIndex' ).val( periodIndex );
-                $( '#contentDiv' ).load( 'loadForm.action', loadDataValuesAndDisplayModes );
-            } 
-            else
-            {
-                clearEntryForm();
-            }
-        } );
+        clearListById( 'selectedPeriodId' );
+
+        addOptionById( 'selectedPeriodId', '-1', '[ ' + i18n_select_period + ' ]' );
+
+        for ( i in periods )
+        {
+            addOptionById( 'selectedPeriodId', periods[i].id, periods[i].name );
+        }
+        
+        var previousPeriodType = currentDataSetId ? dataSets[currentDataSetId].periodType : null;
+
+        if ( periodId && periodId != -1 && previousPeriodType && previousPeriodType == periodType ) //TODO if periodValid
+        {
+            showLoader();
+            $( '#selectedPeriodId' ).val( periodId );
+            loadForm( periodId, dataSetId );
+        } 
+        else
+        {
+            clearEntryForm();
+        }
+        
+    	currentDataSetId = dataSetId;
     }
 }
 
 // -----------------------------------------------------------------------------
-// DisplayMode Selection
-// -----------------------------------------------------------------------------
-
-function displayModeSelected()
-{
-    showLoader();
-
-    var url = 'loadForm.action?displayMode=' + $( "input[name='displayMode']:checked" ).val();
-
-    $( '#contentDiv' ).load( url, loadDataValues );
-}
-
-// -----------------------------------------------------------------------------
 // Period Selection
 // -----------------------------------------------------------------------------
 
 function periodSelected()
 {
-    var periodName = $( '#selectedPeriodIndex :selected' ).text();
+    var periodName = $( '#selectedPeriodId :selected' ).text();
+    var dataSetId = $( '#selectedDataSetId' ).val();
 
     $( '#currentPeriod' ).html( periodName );
 
-    var periodIndex = $( '#selectedPeriodIndex' ).val();
+    var periodId = $( '#selectedPeriodId' ).val();
     
-    if ( periodIndex && periodIndex != -1 )
+    if ( periodId && periodId != -1 )
     {
         showLoader();
         
         if ( dataEntryFormIsLoaded )
         {
-        	loadDataValuesAndDisplayModes();
+        	loadDataValues();
         }
         else
         {
-        	var url = 'loadForm.action?selectedPeriodIndex=' + periodIndex;
-        	
-        	$( '#contentDiv' ).load( url, loadDataValuesAndDisplayModes );
+        	loadForm( periodId, dataSetId );
         }
     }
 }
@@ -223,18 +230,12 @@
 	displayEntryFormCompleted();
 }
 
-function loadDataValuesAndDisplayModes()
-{
-	insertDataValues();
-	setDisplayModes();
-	displayEntryFormCompleted();
-}
-
 function insertDataValues()
 {
 	var valueMap = new Array();
 	
-	var periodIndex = $( '#selectedPeriodIndex' ).val();
+	var periodId = $( '#selectedPeriodId' ).val();
+    var dataSetId = $( '#selectedDataSetId' ).val();
 	
 	// Clear existing values and colors
 	
@@ -247,7 +248,7 @@
 	$( '[name="min"]' ).html( '' );
 	$( '[name="max"]' ).html( '' );
 	
-	$.getJSON( 'getDataValues.action', { selectedPeriodIndex:periodIndex }, function( json ) 
+	$.getJSON( 'getDataValues.action', { periodId:periodId, dataSetId:dataSetId }, function( json ) 
 	{
 		// Set data values, works for select lists too as data value = select value
 	
@@ -296,46 +297,12 @@
 	} );
 }
 
-function setDisplayModes()
-{
-    $.getJSON( 'loadDisplayModes.action', function( json )
-    {
-        $( '#displayModeCustom' ).removeAttr( 'disabled' );
-        $( '#displayModeSection' ).removeAttr( 'disabled' );
-        $( '#displayModeDefault' ).removeAttr( 'disabled' );
-
-        $( '#displayModeCustom' ).removeAttr( 'checked' );
-        $( '#displayModeSection' ).removeAttr( 'checked' );
-        $( '#displayModeDefault' ).removeAttr( 'checked' );
-
-        if ( json.displayMode == 'customform' )
-        {
-            $( '#displayModeCustom' ).attr( 'checked', 'checked' );
-        } 
-        else if ( json.displayMode == 'sectionform' )
-        {
-            $( '#displayModeSection' ).attr( 'checked', 'checked' );
-        } 
-        else
-        {
-            $( '#displayModeDefault' ).attr( 'checked', 'checked' );
-        }
-
-        if ( !json.customForm )
-        {
-            $( '#displayModeCustom' ).attr( 'disabled', 'disabled' );
-        }
-        if ( !json.sectionForm )
-        {
-            $( '#displayModeSection' ).attr( 'disabled', 'disabled' );
-        }
-    } );
-}
-
 function displayEntryFormCompleted()
 {
     addEventListeners();
-    enable( 'validationButton' );
+    $( '#validationButton' ).removeAttr( 'disabled' );
+    $( '#defaultForm' ).removeAttr( 'disabled' );
+    
     dataEntryFormIsLoaded = true;
     hideLoader();
 }
@@ -416,10 +383,13 @@
 
     if ( confirmed )
     {
+		var periodId = $( '#selectedPeriodId' ).val();
+    	var dataSetId = $( '#selectedDataSetId' ).val();
+		
         $( '#completeButton' ).attr( 'disabled', 'disabled' );
         $( '#undoButton' ).removeAttr( 'disabled' );
 
-        $.getJSON( 'getValidationViolations.action', registerCompleteDataSet ).error( function()
+        $.getJSON( 'getValidationViolations.action', { periodId:periodId, dataSetId:dataSetId }, registerCompleteDataSet ).error( function()
         {
             $( '#completeButton' ).removeAttr( 'disabled' );
             $( '#undoButton' ).attr( 'disabled', 'disabled' );
@@ -431,9 +401,12 @@
 
 function registerCompleteDataSet( json )
 {
+	var periodId = $( '#selectedPeriodId' ).val();
+    var dataSetId = $( '#selectedDataSetId' ).val();
+		
     if ( json.response == 'success' )
     {
-        $.getJSON( 'registerCompleteDataSet.action', function()
+        $.getJSON( 'registerCompleteDataSet.action', { periodId:periodId, dataSetId:dataSetId }, function()
         {
         } ).error( function()
         {
@@ -445,7 +418,9 @@
     } 
     else
     {
-        window.open( 'validate.action', '_blank', 'width=800, height=400, scrollbars=yes, resizable=yes' );
+    	var url = 'validate.action?periodId=' + periodId + '&dataSetId=' + dataSetId;
+    	
+        window.open( url, '_blank', 'width=800, height=400, scrollbars=yes, resizable=yes' );
     }
 }
 
@@ -455,10 +430,13 @@
 
     if ( confirmed )
     {
+		var periodId = $( '#selectedPeriodId' ).val();
+    	var dataSetId = $( '#selectedDataSetId' ).val();
+		
         $( '#completeButton' ).removeAttr( 'disabled' );
         $( '#undoButton' ).attr( 'disabled', 'disabled' );
 
-        $.getJSON( 'undoCompleteDataSet.action', function()
+        $.getJSON( 'undoCompleteDataSet.action', { periodId:periodId, dataSetId:dataSetId }, function()
         {
         } ).error( function()
         {
@@ -476,7 +454,12 @@
 
 function validate()
 {
-    window.open( 'validate.action', '_blank', 'width=800, height=400, scrollbars=yes, resizable=yes' );
+	var periodId = $( '#selectedPeriodId' ).val();
+    var dataSetId = $( '#selectedDataSetId' ).val();
+		
+	var url = 'validate.action?periodId=' + periodId + '&dataSetId=' + dataSetId;
+	
+    window.open( url, '_blank', 'width=800, height=400, scrollbars=yes, resizable=yes' );
 }
 
 // -----------------------------------------------------------------------------
@@ -485,13 +468,10 @@
 
 function viewHist( dataElementId, optionComboId )
 {
-    viewHistory( dataElementId, optionComboId, true );
-}
-
-function viewHistory( dataElementId, optionComboId, showComment )
-{
+	var periodId = $( '#selectedPeriodId' ).val();
+	
     window.open( 'viewHistory.action?dataElementId=' + dataElementId + '&optionComboId=' + optionComboId
-            + '&showComment=' + showComment, '_blank', 'width=580,height=710,scrollbars=yes' );
+            + '&periodId=' + periodId + '&showComment=true', '_blank', 'width=580,height=710,scrollbars=yes' );
 }
 
 function closeCurrentSelection()

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/history.js'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/history.js	2011-07-12 14:04:13 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/history.js	2011-07-20 21:38:30 +0000
@@ -11,16 +11,17 @@
 {
 	var commentValue = $( '#commentTextArea' ).val();
 	
-	var commentSaver = new CommentSaver( currentDataElementId, currentOptionComboId, currentOrganisationUnitId, commentValue );
+	var commentSaver = new CommentSaver( currentDataElementId, currentOptionComboId, currentOrganisationUnitId, currentPeriodId, commentValue );
 	
 	commentSaver.save();
 }
 
-function CommentSaver( dataElementId_, optionComboId_, organisationUnitId_, value_ )
+function CommentSaver( dataElementId_, optionComboId_, organisationUnitId_, periodId_, value_ )
 {	
     var dataElementId = dataElementId_;
     var optionComboId = optionComboId_;
     var organisationUnitId = organisationUnitId_;
+    var periodId = periodId_;
     var value = value_;
     
     this.save = function()
@@ -28,7 +29,7 @@
     	markComment( COLOR_YELLOW );
     	
         var url = 'saveComment.action?organisationUnitId=' + organisationUnitId + '&dataElementId=' +
-                dataElementId + '&optionComboId=' + optionComboId + '&comment=' + value;
+                dataElementId + '&optionComboId=' + optionComboId + '&periodId=' + periodId + '&comment=' + value;
         
         $.ajax( { url: url, dataType: 'json', success: handleResponse, error: handleError } );
     };

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm	2011-07-18 10:22:08 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm	2011-07-21 11:52:46 +0000
@@ -27,6 +27,17 @@
 #foreach( $indicator in $indicators )
 indicatorFormulas['${indicator.id}'] = '($!{indicator.explodedNumerator})/($!{indicator.explodedDenominator})*($!{indicator.indicatorType.factor})';
 #end
+
+dataSets = {
+#set( $size3 = $dataSets.size() )
+#foreach( $dataSet in $dataSets )
+"${dataSet.id}": {
+"id":"${dataSet.id}",
+"name":"$!encoder.jsonEncode( ${dataSet.name} )",
+"periodType":"$!encoder.jsonEncode( ${dataSet.periodType.name} )" 
+}#if( $velocityCount < $size3 ),#end
+#end };
+
 </script>
 
 <h3>$i18n.getString( "data_entry" ) #openHelp( "dataEntry" )</h3>
@@ -38,14 +49,9 @@
 </div>
 
 <div id="actions" style="">	
-    <input type="button" value="$i18n.getString( 'run_validation' )" onclick="javascript:validate()" id="validationButton" style="width:150px;" disabled="disabled"/><br/><br/>
+    <input type="button" value="$i18n.getString( 'run_validation' )" onclick="validate()" id="validationButton" style="width:150px;" disabled="disabled"/><br/><br/>
 
-    <label for="displayModeCustom">$i18n.getString( "use_custom_form" )</label>
-    <input type="radio" id="displayModeCustom" name="displayMode" value="customform" disabled="disabled" onclick="displayModeSelected()"><br>
-    <label for="displayModeSection">$i18n.getString( "use_section_form" )</label>
-	<input type="radio" id="displayModeSection" name="displayMode" value="sectionform" disabled="disabled" onclick="displayModeSelected()"><br>
-	<label for="displayModeDefault">$i18n.getString( "use_default_form" )</label>
-	<input type="radio" id="displayModeDefault" name="displayMode" value="defaultform" disabled="disabled" onclick="displayModeSelected()"><br><br>
+    <input type="checkbox" id="defaultForm" onclick="loadDefaultForm()" disabled="disabled"><label for="defaultForm">$i18n.getString( "use_default_form" )</label><br>
 </div>
 
 <table>
@@ -58,8 +64,8 @@
 		<td><select id="selectedDataSetId" name="selectedDataSetId" style="width:350px" onchange="dataSetSelected()" disabled="disabled"></select></td>
 	</tr>	
 	<tr>
-		<td><label for="selectedPeriodIndex">$i18n.getString( "period" )</label></td>
-		<td><select id="selectedPeriodIndex" name="selectedPeriodIndex" style="width:227px" onchange="periodSelected()" disabled="disabled"></select>
+		<td><label for="selectedPeriodId">$i18n.getString( "period" )</label></td>
+		<td><select id="selectedPeriodId" name="selectedPeriodId" style="width:227px" onchange="periodSelected()" disabled="disabled"></select>
 			<input type="button" id="prevButton" style="width:60px" value="$i18n.getString( 'prev' )" title="$i18n.getString('earlier_periods')" onclick="previousPeriodsSelected()" disabled="disabled"><input 
 				   type="button" id="nextButton" style="width:60px" value="$i18n.getString( 'next' )" title="$i18n.getString('later_periods')" onclick="nextPeriodsSelected()" disabled="disabled">
 		</td>