/*
 * ComponentModel.java
 *
 * Created on 9 novembre 2007, 10:31
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */


package fr.gouv.finances.cp.xemelios.common.components;

import fr.gouv.finances.cp.utils.xml.marshal.InvalidXmlDefinition;
import fr.gouv.finances.cp.utils.xml.marshal.XmlAttributes;
import fr.gouv.finances.cp.utils.xml.marshal.XmlMarshallable;
import fr.gouv.finances.cp.utils.xml.marshal.XmlOutputter;
import javax.xml.namespace.QName;
import org.xml.sax.Attributes;

/**
 *
 * @author chm
 */
public class ComponentModel implements XmlMarshallable {
    public static final transient String TAG = "component";
    public static final transient QName QN = new QName(TAG);
    
    private String tagName;
    private QName qn;
    
    private String id, description, version;
    
    /** Creates a new instance of ComponentModel */
    public ComponentModel(QName tagName) {
        super();
        this.qn=tagName;
        this.tagName = qn.getLocalPart();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public void addCharacterData(String cData) throws org.xml.sax.SAXException { }

    public void addChild(XmlMarshallable child, QName tagName) throws org.xml.sax.SAXException { }

    public XmlMarshallable getAttributes(XmlAttributes attributes) throws org.xml.sax.SAXException {
        id = attributes.getValue("id");
        description = attributes.getValue("description");
        version = attributes.getValue("version");
        return this;
    }

    public void marshall(XmlOutputter output) {
        output.startTag(tagName);
        output.addAttribute("id",id);
        output.addAttribute("description",description);
        output.addAttribute("version",version);
        output.endTag(tagName);
    }

    public void validate() throws InvalidXmlDefinition { }

    public ComponentModel clone() {
        return this;
    }
    public boolean isNewerThan(ComponentModel other) {
        if(!getId().equals(other)) throw new IllegalArgumentException(other.getId()+" is different than "+getId());
        return compareReleases(getVersion(),other.getVersion())>0;
    }
    public boolean isNewerOrEqualThan(ComponentModel other) {
        if(!getId().equals(other)) throw new IllegalArgumentException(other.getId()+" is different than "+getId());
        return compareReleases(getVersion(),other.getVersion())>=0;
    }
    public boolean isNewerOrEqualThan(String otherVersion) {
        return compareReleases(getVersion(),otherVersion)>=0;
    }
    
    private static int compareReleases(String r1, String r2) {
        String[] s1 = splitRelease(r1);
        String[] s2 = splitRelease(r2);
        int ret = 0;
        for(int i=0;i<Math.min(s1.length,s2.length);i++) {
            int a = -1, b = -1;
            try { a = Integer.parseInt(s1[i]); } catch(Throwable t) {}
            try { b = Integer.parseInt(s2[i]); } catch(Throwable t) {}
            if(a!=-1 && b!=-1) {
                if(a<b) ret = -1;
                else if(a==b) ret = 0;
                else ret = 1;
            } else {
                ret = s1[i].compareTo(s2[i]);
            }
            if(ret!=0) {
                return ret;
            }
        }
        if(s1.length>s2.length) ret = 1;
        else if(s1.length<s2.length) ret = -1;
        return ret;
    }
    private static String[] splitRelease(String r) {
        return r.split("\\.");
    }

    public XmlMarshallable getChildToModify(String uri, String localName, String qName, Attributes atts) {
        return null;
    }

    public QName getQName() {
        return qn;
    }
}
