/*
 * generated by Xtext 2.12.0
 */
package com.minres.rdl.ui.labeling

import com.google.inject.Inject
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider
import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider
import com.minres.rdl.rdl.ComponentDefinition
import com.minres.rdl.rdl.ExplicitPropertyAssignment
import com.minres.rdl.rdl.ImmediateInstantiation
import com.minres.rdl.rdl.ComponentInstance
import com.minres.rdl.rdl.PropertyAssignment
import com.minres.rdl.rdl.PropertyAssignmentRhs
import com.minres.rdl.rdl.RValue
import com.minres.rdl.IntegerWithRadix
import com.minres.rdl.rdl.PropertyEnum
import com.minres.rdl.rdl.RValueConstant
import com.minres.rdl.rdl.PropertyModifier
import com.minres.rdl.rdl.ComponentDefinitionType
import com.minres.rdl.rdl.EnumDefinition
import com.minres.rdl.rdl.NamedInstantiation
import com.minres.rdl.rdl.PostPropertyAssignment
import com.minres.rdl.rdl.InstanceRef
import com.minres.rdl.rdl.InstancePropertyRef
import com.minres.rdl.rdl.EnumEntry
import com.minres.rdl.rdl.EnumProperty

/**
 * Provides labels for EObjects.
 * 
 * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider
 */
class RDLLabelProvider extends DefaultEObjectLabelProvider {

	@Inject
	new(AdapterFactoryLabelProvider delegate) {
		super(delegate);
	}

	// Labels and icons can be computed like this:
	
//	def text(Greeting ele) {
//		'A greeting to ' + ele.name
//	}
//
//	def image(Greeting ele) {
//		'Greeting.gif'
//	}

	def text(ComponentDefinition e){
		if(e.immediateInstantiation!==null){
			if(e.name!==null)
				text(e.immediateInstantiation)+' ('+e.name+')'
			else
				text(e.immediateInstantiation)
		}else if(e.name!==null){
			e.type.literal+' '+e.name	
		} else{
			val pa = e.propertyAssignments.findFirst[PropertyAssignment pa | 
				pa instanceof ExplicitPropertyAssignment && (pa as ExplicitPropertyAssignment).name==PropertyEnum.NAME
			]
			e.type.literal+' '+ text((pa as ExplicitPropertyAssignment).rhs)
		}
	} 
	
	def text(ExplicitPropertyAssignment e){
		var res = ""
		if(e.modifier!=PropertyModifier.UNDEFINED)
			res+=e.modifier.literal + ' '
		res+=e.name
		if(e.rhs!==null)
			res+=' = '+text(e.rhs)
		return res
	} 
	
	def text(PostPropertyAssignment e){
		var res = ""
		res+=text(e.instance)
		if(e.property !== null)
			res+='->'+e.property.name
		else if(e.propertyEnum != PropertyEnum.UNSPECIFIED)
			res+='->'+e.propertyEnum.literal
		return res
	} 
	
	def String text(InstanceRef e){
		if(e.tail!==null)
			e.instance.name+'.'+text(e.tail)
		else
			e.instance.name
	}
	
	def text( ImmediateInstantiation e){
		e.componentInstances.map[text(it)].join(", ")
	} 
	
	def text( ComponentInstance e){
		var res = e.name
		if(e.range !== null)
			res+='['+(if(e.range.size!==null) e.range.size.toString else e.range.start+':'+e.range.end)+']'
		if(e.address!==null)
			res+=' @'+e.address
		return res
	}

	def text( PropertyAssignmentRhs e){
		if(e.value!== null)
			text(e.value)
		else if(e.instPropRef!==null)
			text(e.instPropRef)
		else if(e.enumRef!==null)
			text(e.enumRef)
	}

	def text(InstancePropertyRef ref){
		text(ref.instance) +  
		if(ref.property!==null) '->' + ref.property.name 
			else if(ref.propertyEnum != PropertyEnum.UNSPECIFIED) '->' +ref.propertyEnum.literal else ''
	}

	def text( RValue e){
		if(e.str!==null){
			elipse(e.str)
		} else if(e.^val!=RValueConstant.UNDEFINED)
			return e.^val.literal
		else if(e.num!==null){
			val num = e.num as IntegerWithRadix
			return num.toString
		}
	}
	
	def elipse(String string) {
			val pos = string.indexOf('\n')
			if(pos>0) 
				return string.substring(0, pos-1)+'...'
			else if(string.length>30)
				return string.substring(0, 30)+'...'
			else
				return string
	}
	
	def text(NamedInstantiation e){
		e.componentInstances.map[text(it)].join(", ")+' ('+e.component.name+')'
	}
 
	def text(EnumEntry e){
		if(e.index !== null)
			e.name + '=' + e.index.toString
		else
			e.name+'='+e.properties.map[
				text(it)
			].join(',')
	}

	def text(EnumProperty e){
		e.name+'='+elipse(e.value)
	}

	def image(ComponentDefinition e){
		switch(e.type){
			case ComponentDefinitionType.ADDRMAP: return 'A.png'
			case ComponentDefinitionType.FIELD: return 'F.png'
			case ComponentDefinitionType.REG: return 'R.png'
			case ComponentDefinitionType.REGFILE: return 'R.png'
			case ComponentDefinitionType.SIGNAL: return 'S.png'
		}
	}
	

	def image(PropertyAssignmentRhs e){
		if(e.value!== null)
			'V.png'
		else if(e.instPropRef!==null)
			image(e.instPropRef)
		else if(e.enumRef!==null)
			'E.png'
	}

	def image(InstancePropertyRef ref){
		if(ref.property!==null) 
			'P.png' 
		else if(ref.propertyEnum != PropertyEnum.UNSPECIFIED) 
			'E.png'
		else
			'I.png'
	}

	def image(EnumDefinition e){
		'E.png'
	}

	def image(ExplicitPropertyAssignment e){
		'P.png'
	}

	def image(PostPropertyAssignment e){
		'P.png'
	}

	def image(NamedInstantiation e){
		'I.png'
	}
	
	def image(EnumEntry v){
		'V.png'
	}

	def image(EnumProperty e){
		'P.png'
	}
}
