/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed 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.
 */

package standardDsls

import com.intellij.psi.PsiClassType
import com.intellij.psi.PsiField
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiParameter
/**
 * Hackergarten contribution
 *
 * @author Ryan Applegate
 * @author Andres Almiray
 */

def capitalize(String str) {
  if (str == null || str.trim().length() == 0) return str
  if (str.length() == 1) return str.toUpperCase()
  return str.substring(0, 1).toUpperCase() + str.substring(1)
}

def uncapitalize(String str) {
  if (str == null || str.trim().length() == 0) return str
  if (str.length() == 1) return str.toLowerCase()
  return str.substring(0, 1).toLowerCase() + str.substring(1)
}

contributor(ctype: hasField(hasAnnotation('groovy.beans.ListenerList'))) {
  for (PsiField field : psiClass?.fields?.grep {it.hasAnnotation('groovy.beans.ListenerList')}) {
    def fieldType = field.type
    if (!(fieldType instanceof PsiClassType)) {
      continue
    }

    def type = fieldType.parameters ? fieldType.parameters[0] : null
    if (!type) return
    String typeClassName = type.className
    method name: 'add' + typeClassName, type: void, params: [listener: typeClassName]
    method name: 'remove' + typeClassName, type: void, params: [listener: typeClassName]
    method name: 'get' + typeClassName + 's', type: typeClassName + '[]'

    for (PsiMethod m : findClass(type.getDeepComponentType().canonicalText).getMethods()) {
      if (m == null) continue
      String methodName = m.getName()
      methodName = capitalize(methodName[0])
      Map params = [:]
      for (PsiParameter param : m.parameterList.parameters) {
        String paramName = param.typeElement.text
        paramName = uncapitalize(paramName[0])
        params[paramName] = param.type.getDeepComponentType().canonicalText
      }

      method name: 'fire' + methodName, type: 'void', params: params
    }
  }
}