#set( $filename = "ProtocolVersion.java" )
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
* 
*   http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/

/*
* This file is auto-generated by $generator - do not modify.
* Supported AMQP versions:
#foreach( $version in $model.getVersionSet() )
* $version.getMajor()-$version.getMinor()
#end
*/

package org.apache.qpid.framing;

import java.util.SortedSet;
import java.util.Collections;
import java.util.TreeSet;
import java.util.Map;
import java.util.HashMap;


public class ProtocolVersion  implements Comparable
{
    private final byte _majorVersion;
    private final byte _minorVersion;
    private final String _stringFormat;


    public ProtocolVersion(byte majorVersion, byte minorVersion)
    {
        _majorVersion = majorVersion;
        _minorVersion = minorVersion;
        _stringFormat = _majorVersion+"-"+_minorVersion;
    }

    public byte getMajorVersion()
    {
        return _majorVersion;
    }

    public byte getMinorVersion()
    {
        return _minorVersion;
    }

    public byte getActualMinorVersion()
    {
        return _minorVersion > 90 ? (byte) (_minorVersion / 10) : _minorVersion;
    }


    public byte getRevisionVersion()
    {
        return _minorVersion > 90 ? (byte) (_minorVersion % 10) : (byte) 0;
    }

    public String toString()
    {
        return _stringFormat;
    }


    public int compareTo(Object o)
    {
        ProtocolVersion pv = (ProtocolVersion) o;
		
		/* 
		 * 0-8 has it's major and minor numbers the wrong way round (it's actually 8-0)...
		 * so we need to deal with that case specially
		 */
		
        if((_majorVersion == (byte) 8) && (_minorVersion == (byte) 0))
		{
		    ProtocolVersion fixedThis = new ProtocolVersion(_minorVersion, _majorVersion);
			return fixedThis.compareTo(pv);
		}
		
		if((pv.getMajorVersion() == (byte) 8) && (pv.getMinorVersion() == (byte) 0))
		{
			ProtocolVersion fixedOther = new ProtocolVersion(pv.getMinorVersion(), pv.getMajorVersion());
		    return this.compareTo(fixedOther);    
		}
		
        if(_majorVersion > pv.getMajorVersion())
        {
            return 1;
        }
        else if(_majorVersion < pv.getMajorVersion())
        {
            return -1;
        }
        else if(_minorVersion > pv.getMinorVersion())
        {
            return 1;
        }
        else if(getMinorVersion() < pv.getMinorVersion())
        {
            return -1;
        }
        else
        {
            return 0;
        }

    }

    public boolean equals(Object o)
    {
        return o != null && (o == this || (compareTo(o) == 0));
    }

    public int hashCode()
    {
        return (0xFF & (int)_minorVersion) | ((0xFF & (int)_majorVersion) << 8);
    }
    
    
    public boolean isSupported()
    {
        return _supportedVersions.contains(this);
    }
    
    public static ProtocolVersion getLatestSupportedVersion()
    {
        return _supportedVersions.last();
    }
    
    private static final SortedSet<ProtocolVersion> _supportedVersions;
	private static final Map<String, ProtocolVersion> _nameToVersionMap =
	                         new HashMap<String, ProtocolVersion>();
    private static final ProtocolVersion _defaultVersion;							 

	
    public static final ProtocolVersion v0_10 = new ProtocolVersion((byte)0,(byte)10);

#foreach( $version in $model.getVersionSet() )
#set( $versionId = "v$version.getMajor()_$version.getMinor()" )
    public static final ProtocolVersion $versionId = new ProtocolVersion((byte)$version.getMajor(),(byte)$version.getMinor());
#end
	
        
    static
    {
        SortedSet<ProtocolVersion> versions = new TreeSet<ProtocolVersion>();

		versions.add(v0_10);
		_nameToVersionMap.put("0-10", v0_10);
#foreach( $version in $model.getVersionSet() )
#set( $versionId = "v$version.getMajor()_$version.getMinor()" )
        versions.add($versionId);
		_nameToVersionMap.put("${version.getMajor()}-${version.getMinor()}", $versionId);
#end
        _supportedVersions = Collections.unmodifiableSortedSet(versions);
		
		
		ProtocolVersion systemDefinedVersion =
		    _nameToVersionMap.get(System.getProperty("org.apache.qpid.amqp_version"));
			
	    _defaultVersion = (systemDefinedVersion == null) 
		                      ? getLatestSupportedVersion() 
							  : systemDefinedVersion;
    }

    
    public static SortedSet<ProtocolVersion> getSupportedProtocolVersions()
    {
        return _supportedVersions;
    }
    
    

    public static ProtocolVersion parse(String name)
    {
        return _nameToVersionMap.get(name);
    }
    
    public static ProtocolVersion defaultProtocolVersion()
    {
        return _defaultVersion;
    }
    

}
