text: const isWeex = typeof WXEnvironment !== 'undefined';
  const isWeexIOS = isWeex && /ios/i.test(WXEnvironment.platform);
  const isWeexAndroid = isWeex && !isWeexIOS;
  
  import GLmethod from '../context-webgl/GLmethod';
  
  const GCanvasModule =
      (typeof weex !== 'undefined' && weex.requireModule) ? (weex.requireModule('gcanvas')) :
          (typeof __weex_require__ !== 'undefined') ? (__weex_require__('@weex-module/gcanvas')) : {};
  
  let isDebugging = false;
  
  let isComboDisabled = false;
  
  const logCommand = (function () {
      const methodQuery = [];
      Object.keys(GLmethod).forEach(key => {
          methodQuery[GLmethod[key]] = key;
      })
      const queryMethod = (id) => {
          return methodQuery[parseInt(id)] || 'NotFoundMethod';
      }
      const logCommand = (id, cmds) => {
          const mId = cmds.split(',')[0];
          const mName = queryMethod(mId);
          console.log(`=== callNative - componentId:${id}; method: ${mName}; cmds: ${cmds}`);
      }
      return logCommand;
  })();
  
  function joinArray(arr, sep) {
      let res = '';
      for (let i = 0; i < arr.length; i++) {
          if (i !== 0) {
              res += sep;
          }
          res += arr[i];
      }
      return res;
  }
  
  const commandsCache = {}
  
  const GBridge = {
  
      callEnable: (ref, configArray) => {
  
          commandsCache[ref] = [];
  
          return GCanvasModule.enable({
              componentId: ref,
              config: configArray
          });
      },
  
      callEnableDebug: () => {
          isDebugging = true;
      },
  
      callEnableDisableCombo: () => {
          isComboDisabled = true;
      },
  
      callSetContextType: function (componentId, context_type) {
          GCanvasModule.setContextType(context_type, componentId);
      },
  
      callReset: function(id){
          GCanvasModule.resetComponent && canvasModule.resetComponent(componentId);
      },
  
      render: isWeexIOS ? function (componentId) {
          return GCanvasModule.extendCallNative({
              contextId: componentId,
              type: 0x60000001
          });
      } : function (componentId) {
          return callGCanvasLinkNative(componentId, 0x60000001, 'render');
      },
  
      render2d: isWeexIOS ? function (componentId, commands) {
  
          if (isDebugging) {
              console.log('>>> >>> render2d ===');
              console.log('>>> commands: ' + commands);
          }
  
          GCanvasModule.render(commands, componentId);
  
      } : function (componentId, commands) {
  
          if (isDebugging) {
              console.log('>>> >>> render2d ===');
              console.log('>>> commands: ' + commands);
          }
  
          callGCanvasLinkNative(componentId, 0x20000001, commands);
      },
  
      hasEnterBackground: isWeexIOS ? function (callback) {
          GCanvasModule.hasEnterBackground((result) => {
              callback(result);
          });
      } : function () {
          
      },
  
      callExtendCallNative: isWeexIOS ? function (componentId, cmdArgs) {
  
          throw 'should not be here anymore ' + cmdArgs;
  
      } : function (componentId, cmdArgs) {
  
          throw 'should not be here anymore ' + cmdArgs;
  
      },
  
  
      flushNative: isWeexIOS ? function (componentId) {
  
          const cmdArgs = joinArray(commandsCache[componentId], ';');
          commandsCache[componentId] = [];
  
          if (isDebugging) {
              console.log('>>> >>> flush native ===');
              console.log('>>> commands: ' + cmdArgs);
          }
  
          const result = GCanvasModule.extendCallNative({
              "contextId": componentId,
              "type": 0x60000000,
              "args": cmdArgs
          });
  
          const res = result && result.result;
  
          if (isDebugging) {
              console.log('>>> result: ' + res);
          }
  
          return res;
  
      } : function (componentId) {
  
          const cmdArgs = joinArray(commandsCache[componentId], ';');
          commandsCache[componentId] = [];
  
          if (isDebugging) {
              console.log('>>> >>> flush native ===');
              console.log('>>> commands: ' + cmdArgs);
          }
  
          const result = callGCanvasLinkNative(componentId, 0x60000000, cmdArgs);
  
          if (isDebugging) {
              console.log('>>> result: ' + result);
          }
  
          return result;
      },
  
      callNative: function (componentId, cmdArgs, cache) {
  
          if (isDebugging) {
              logCommand(componentId, cmdArgs);
          }
  
          commandsCache[componentId].push(cmdArgs);
  
          if (!cache || isComboDisabled) {
              return GBridge.flushNative(componentId);
          } else {
              return undefined;
          }
      },
  
      texImage2D(componentId, ...args) {
          if (isWeexIOS) {
              if (args.length === 6) {
                  const [target, level, internalformat, format, type, image] = args;
                  GBridge.callNative(
                      componentId,
                      GLmethod.texImage2D + ',' + 6 + ',' + target + ',' + level + ',' + internalformat + ',' + format + ',' + type + ',' + image.src
                  )
              } else if (args.length === 9) {
                  const [target, level, internalformat, width, height, border, format, type, image] = args;
                  GBridge.callNative(
                      componentId,
                      GLmethod.texImage2D + ',' + 9 + ',' + target + ',' + level + ',' + internalformat + ',' + width + ',' + height + ',' + border + ',' +
                      + format + ',' + type + ',' + (image ? image.src : 0)
                  )
              }
          } else if (isWeexAndroid) {
              if (args.length === 6) {
                  const [target, level, internalformat, format, type, image] = args;
                  GCanvasModule.texImage2D(componentId, target, level, internalformat, format, type, image.src);
              } else if (args.length === 9) {
                  const [target, level, internalformat, width, height, border, format, type, image] = args;
                  GCanvasModule.texImage2D(componentId, target, level, internalformat, width, height, border, format, type, (image ? image.src : 0));
              }
          }
      },
  
      texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image) {
          if (isWeexIOS) {
              if (arguments.length === 8) {
                  GBridge.callNative(
                      componentId,
                      GLmethod.texSubImage2D + ',' + 6 + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset, + ',' + format + ',' + type + ',' + image.src
                  )
              }
          } else if (isWeexAndroid) {
              GCanvasModule.texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image.src);
          }
      },
  
      bindImageTexture(componentId, src, imageId) {
          console.log(src, imageId);
          GCanvasModule.bindImageTexture([src, imageId], componentId);
      },
  
      perloadImage([url, id], callback) {
          GCanvasModule.preLoadImage([url, id], function (image) {
              image.url = url;
              image.id = id;
              callback(image);
          });
      }
  }
  
  export default GBridge;