/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */

CLASS({
  name: 'MessagesExtractor',
  package: 'foam.i18n',
  extendsModel: 'foam.i18n.Visitor',

  requires: [
    'foam.i18n.Message',
    'foam.i18n.MessageBundle',
    'foam.i18n.Placeholder'
  ],
  imports: [ 'console' ],

  properties: [
    {
      model_: 'foam.core.types.DAOProperty',
      name: 'dao',
      lazyFactory: function() { return []; }
    },
    {
      name: 'messageBundleFactory',
      lazyFactory: function() {
        return this.MessageBundle.create;
      }
    },
    {
      name: 'messageFactory',
      lazyFactory: function() {
        return this.Message.create;
      }
    }
  ],

  methods: [
    {
      name: 'visitMessage',
      code: function(model, msg) {
        var modelPrefix = model.translationHint ?
            model.translationHint + ' ' : '';
        var placeholders = msg.placeholders.map(function(p) {
          return this.Placeholder.create(p);
        }.bind(this));
        var i18nMsg = this.messageFactory({
          id: this.idGenerator.getMessageId(model, msg),
          name: msg.name,
          value: msg.value,
          meaning: msg.meaning,
          placeholders: placeholders,
          description: modelPrefix + msg.translationHint
        });
        this.dao.put(i18nMsg);
        return i18nMsg;
      }
    },
    {
      name: 'visitAction',
      code: function(model, action) {
        var modelPrefix = model.translationHint ?
            model.translationHint + ' ' : '';
        var msgs = [];
        var i18nMsg;
        if ( action.translationHint ) {
          if ( action.label ) {
            i18nMsg = this.messageFactory({
              id: this.idGenerator.getActionTextLabelId(model, action),
              name: action.name + 'Label',
              value: action.label,
              description: modelPrefix + action.translationHint +
                  ' (text label)'
            });
            this.dao.put(i18nMsg);
            msgs.push(i18nMsg);
          }
          if ( action.speechLabel ) {
            i18nMsg = this.messageFactory({
              id: this.idGenerator.getActionSpeechLabelId(model, action),
              name: action.name + 'SpeechLabel',
              value: action.speechLabel,
              description: modelPrefix + action.translationHint +
                  ' (speech label)'
            });
            this.dao.put(i18nMsg);
            msgs.push(i18nMsg);
          }
        }
        return msgs;
      }
    },
    {
      name: 'achromeMessages',
      code: function(ret) {
        var msgs = {};
        this.dao.select({
          put: function(msg) { msgs[msg.id] = msg.toChromeMessage(); },
          eof: function() { ret(msgs); }
        });
      }
    },
    {
      name: 'amessages',
      code: function(ret) {
        this.abuildMessages_(ret);
      }
    },
    {
      name: 'amessagesFile',
      code: function(dataId, ret) {
        this.abuildMessages_(function(msgs) {
          msgs.id = dataId;
          ret('__DATA(' +
              JSONUtil.compact.where(NOT_TRANSIENT).stringify(msgs) + ');');
        });
      }
    },
    {
      name: 'abuildMessages_',
      code: function(ret) {
        var msgs = this.messageBundleFactory();
        var arr = msgs.messages;
        this.dao.select({
          put: function(msg) { arr.push(msg); }.bind(this),
          eof: function() { ret(msgs); }
        });
      }
    },
    {
      name: 'ai18n',
      code: function(format, ret) {
        throw 'ERROR: i18n output format "' + format + '" not recognized';
      }
    }
  ]
});

@@ -1096,34 +1096,59 @@
 ageBundle.create
+.bind(this.MessageBundle)
 ;%0A
-
       %7D%0A    %7D,%0A 
@@ -1248,16 +1248,185 @@
 e.create
+.bind(this.Message);%0A      %7D%0A    %7D,%0A    %7B%0A      name: 'placeholderFactory',%0A      lazyFactory: function() %7B%0A        return this.Placeholder.create.bind(this.Placeholder)
 ;%0A      
@@ -1693,33 +1693,33 @@
     return this.
-P
+p
 laceholder.creat
@@ -1712,23 +1712,23 @@
 ceholder
-.create
+Factory
 (p);%0A   

Use placeholder factory, consistent with message and message bundle generation strategies